xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_fzc.c (revision 86ef0a63)
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  */
214ba491f5SMichael Speer 
2244961713Sgirish /*
234ba491f5SMichael Speer  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2444961713Sgirish  * Use is subject to license terms.
2544961713Sgirish  */
2644961713Sgirish 
2744961713Sgirish #include	<nxge_impl.h>
2844961713Sgirish #include	<npi_mac.h>
2944961713Sgirish #include	<npi_rxdma.h>
30678453a8Sspeer #include	<nxge_hio.h>
3144961713Sgirish 
3244961713Sgirish #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
3344961713Sgirish static int	nxge_herr2kerr(uint64_t);
344df55fdeSJanie Lu static uint64_t nxge_init_hv_fzc_lp_op(p_nxge_t, uint64_t,
354df55fdeSJanie Lu     uint64_t, uint64_t, uint64_t, uint64_t);
3644961713Sgirish #endif
3744961713Sgirish 
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 
4444961713Sgirish /*
4544961713Sgirish  * The following interfaces are controlled by the
4644961713Sgirish  * function control registers. Some global registers
4744961713Sgirish  * are to be initialized by only byt one of the 2/4 functions.
4844961713Sgirish  * Use the test and set register.
4944961713Sgirish  */
5044961713Sgirish /*ARGSUSED*/
5144961713Sgirish nxge_status_t
nxge_test_and_set(p_nxge_t nxgep,uint8_t tas)5244961713Sgirish nxge_test_and_set(p_nxge_t nxgep, uint8_t tas)
5344961713Sgirish {
5444961713Sgirish 	npi_handle_t		handle;
5544961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
5644961713Sgirish 
5744961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5844961713Sgirish 	if ((rs = npi_dev_func_sr_sr_get_set_clear(handle, tas))
5952ccf843Smisaki 	    != NPI_SUCCESS) {
6044961713Sgirish 		return (NXGE_ERROR | rs);
6144961713Sgirish 	}
6244961713Sgirish 
6344961713Sgirish 	return (NXGE_OK);
6444961713Sgirish }
6544961713Sgirish 
6644961713Sgirish nxge_status_t
nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep,boolean_t mpc)6744961713Sgirish nxge_set_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t mpc)
6844961713Sgirish {
6944961713Sgirish 	npi_handle_t		handle;
7044961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
7144961713Sgirish 
7244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_set_fzc_multi_part_ctl"));
7344961713Sgirish 
7444961713Sgirish 	/*
7544961713Sgirish 	 * In multi-partitioning, the partition manager
7644961713Sgirish 	 * who owns function zero should set this multi-partition
7744961713Sgirish 	 * control bit.
7844961713Sgirish 	 */
7944961713Sgirish 	if (nxgep->use_partition && nxgep->function_num) {
8044961713Sgirish 		return (NXGE_ERROR);
8144961713Sgirish 	}
8244961713Sgirish 
8344961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
8444961713Sgirish 	if ((rs = npi_fzc_mpc_set(handle, mpc)) != NPI_SUCCESS) {
8544961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
8652ccf843Smisaki 		    "<== nxge_set_fzc_multi_part_ctl"));
8744961713Sgirish 		return (NXGE_ERROR | rs);
8844961713Sgirish 	}
8944961713Sgirish 
9044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_set_fzc_multi_part_ctl"));
9144961713Sgirish 
9244961713Sgirish 	return (NXGE_OK);
9344961713Sgirish }
9444961713Sgirish 
9544961713Sgirish nxge_status_t
nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep,boolean_t * mpc_p)9644961713Sgirish nxge_get_fzc_multi_part_ctl(p_nxge_t nxgep, boolean_t *mpc_p)
9744961713Sgirish {
9844961713Sgirish 	npi_handle_t		handle;
9944961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
10044961713Sgirish 
10144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
10244961713Sgirish 
10344961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
10444961713Sgirish 	if ((rs = npi_fzc_mpc_get(handle, mpc_p)) != NPI_SUCCESS) {
10544961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
10652ccf843Smisaki 		    "<== nxge_set_fzc_multi_part_ctl"));
10744961713Sgirish 		return (NXGE_ERROR | rs);
10844961713Sgirish 	}
10944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "<== nxge_get_fzc_multi_part_ctl"));
11044961713Sgirish 
11144961713Sgirish 	return (NXGE_OK);
11244961713Sgirish }
11344961713Sgirish 
11444961713Sgirish /*
11544961713Sgirish  * System interrupt registers that are under function zero
11644961713Sgirish  * management.
11744961713Sgirish  */
11844961713Sgirish nxge_status_t
nxge_fzc_intr_init(p_nxge_t nxgep)11944961713Sgirish nxge_fzc_intr_init(p_nxge_t nxgep)
12044961713Sgirish {
12144961713Sgirish 	nxge_status_t	status = NXGE_OK;
12244961713Sgirish 
12344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_init"));
12444961713Sgirish 
12544961713Sgirish 	/* Configure the initial timer resolution */
12644961713Sgirish 	if ((status = nxge_fzc_intr_tmres_set(nxgep)) != NXGE_OK) {
12744961713Sgirish 		return (status);
12844961713Sgirish 	}
12944961713Sgirish 
1302e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
13144961713Sgirish 		/*
13244961713Sgirish 		 * Set up the logical device group's logical devices that
13344961713Sgirish 		 * the group owns.
13444961713Sgirish 		 */
13559ac0c16Sdavemq 		if ((status = nxge_fzc_intr_ldg_num_set(nxgep)) != NXGE_OK)
13659ac0c16Sdavemq 			goto fzc_intr_init_exit;
13744961713Sgirish 
13844961713Sgirish 		/* Configure the system interrupt data */
13959ac0c16Sdavemq 		if ((status = nxge_fzc_intr_sid_set(nxgep)) != NXGE_OK)
14059ac0c16Sdavemq 			goto fzc_intr_init_exit;
14144961713Sgirish 	}
14244961713Sgirish 
14359ac0c16Sdavemq fzc_intr_init_exit:
14459ac0c16Sdavemq 
14544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_init"));
14644961713Sgirish 
14744961713Sgirish 	return (status);
14844961713Sgirish }
14944961713Sgirish 
15044961713Sgirish nxge_status_t
nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep)15144961713Sgirish nxge_fzc_intr_ldg_num_set(p_nxge_t nxgep)
15244961713Sgirish {
15344961713Sgirish 	p_nxge_ldg_t	ldgp;
15444961713Sgirish 	p_nxge_ldv_t	ldvp;
15544961713Sgirish 	npi_handle_t	handle;
15644961713Sgirish 	int		i, j;
15744961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
15844961713Sgirish 
15944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_ldg_num_set"));
16044961713Sgirish 
16144961713Sgirish 	if (nxgep->ldgvp == NULL) {
16244961713Sgirish 		return (NXGE_ERROR);
16344961713Sgirish 	}
16444961713Sgirish 
16544961713Sgirish 	ldgp = nxgep->ldgvp->ldgp;
16644961713Sgirish 	ldvp = nxgep->ldgvp->ldvp;
16744961713Sgirish 	if (ldgp == NULL || ldvp == NULL) {
16844961713Sgirish 		return (NXGE_ERROR);
16944961713Sgirish 	}
17044961713Sgirish 
17144961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
17244961713Sgirish 
17344961713Sgirish 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
17444961713Sgirish 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
17552ccf843Smisaki 		    "==> nxge_fzc_intr_ldg_num_set "
17652ccf843Smisaki 		    "<== nxge_f(Neptune): # ldv %d "
17752ccf843Smisaki 		    "in group %d", ldgp->nldvs, ldgp->ldg));
17844961713Sgirish 
17944961713Sgirish 		for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
18044961713Sgirish 			rs = npi_fzc_ldg_num_set(handle, ldvp->ldv,
18152ccf843Smisaki 			    ldvp->ldg_assigned);
18244961713Sgirish 			if (rs != NPI_SUCCESS) {
18344961713Sgirish 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
18452ccf843Smisaki 				    "<== nxge_fzc_intr_ldg_num_set failed "
18552ccf843Smisaki 				    " rs 0x%x ldv %d ldg %d",
18652ccf843Smisaki 				    rs, ldvp->ldv, ldvp->ldg_assigned));
18744961713Sgirish 				return (NXGE_ERROR | rs);
18844961713Sgirish 			}
18944961713Sgirish 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
19052ccf843Smisaki 			    "<== nxge_fzc_intr_ldg_num_set OK "
19152ccf843Smisaki 			    " ldv %d ldg %d",
19252ccf843Smisaki 			    ldvp->ldv, ldvp->ldg_assigned));
19344961713Sgirish 		}
19444961713Sgirish 	}
19544961713Sgirish 
19644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_ldg_num_set"));
19744961713Sgirish 
19844961713Sgirish 	return (NXGE_OK);
19944961713Sgirish }
20044961713Sgirish 
20144961713Sgirish nxge_status_t
nxge_fzc_intr_tmres_set(p_nxge_t nxgep)20244961713Sgirish nxge_fzc_intr_tmres_set(p_nxge_t nxgep)
20344961713Sgirish {
20444961713Sgirish 	npi_handle_t	handle;
20544961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
20644961713Sgirish 
20744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_tmrese_set"));
20844961713Sgirish 	if (nxgep->ldgvp == NULL) {
20944961713Sgirish 		return (NXGE_ERROR);
21044961713Sgirish 	}
21144961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
21244961713Sgirish 	if ((rs = npi_fzc_ldg_timer_res_set(handle, nxgep->ldgvp->tmres))) {
21344961713Sgirish 		return (NXGE_ERROR | rs);
21444961713Sgirish 	}
21544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_tmrese_set"));
21644961713Sgirish 
21744961713Sgirish 	return (NXGE_OK);
21844961713Sgirish }
21944961713Sgirish 
22044961713Sgirish nxge_status_t
nxge_fzc_intr_sid_set(p_nxge_t nxgep)22144961713Sgirish nxge_fzc_intr_sid_set(p_nxge_t nxgep)
22244961713Sgirish {
22344961713Sgirish 	npi_handle_t	handle;
22444961713Sgirish 	p_nxge_ldg_t	ldgp;
22544961713Sgirish 	fzc_sid_t	sid;
22644961713Sgirish 	int		i;
22744961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
22844961713Sgirish 
22944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_fzc_intr_sid_set"));
23044961713Sgirish 	if (nxgep->ldgvp == NULL) {
23144961713Sgirish 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
23252ccf843Smisaki 		    "<== nxge_fzc_intr_sid_set: no ldg"));
23344961713Sgirish 		return (NXGE_ERROR);
23444961713Sgirish 	}
23544961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
23644961713Sgirish 	ldgp = nxgep->ldgvp->ldgp;
23744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
23852ccf843Smisaki 	    "==> nxge_fzc_intr_sid_set: #int %d", nxgep->ldgvp->ldg_intrs));
23944961713Sgirish 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
24044961713Sgirish 		sid.ldg = ldgp->ldg;
24144961713Sgirish 		sid.niu = B_FALSE;
24244961713Sgirish 		sid.func = ldgp->func;
24344961713Sgirish 		sid.vector = ldgp->vector;
24444961713Sgirish 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
24552ccf843Smisaki 		    "==> nxge_fzc_intr_sid_set(%d): func %d group %d "
24652ccf843Smisaki 		    "vector %d",
24752ccf843Smisaki 		    i, sid.func, sid.ldg, sid.vector));
24844961713Sgirish 		rs = npi_fzc_sid_set(handle, sid);
24944961713Sgirish 		if (rs != NPI_SUCCESS) {
25044961713Sgirish 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
25152ccf843Smisaki 			    "<== nxge_fzc_intr_sid_set:failed 0x%x",
25252ccf843Smisaki 			    rs));
25344961713Sgirish 			return (NXGE_ERROR | rs);
25444961713Sgirish 		}
25544961713Sgirish 	}
25644961713Sgirish 
25744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_sid_set"));
25844961713Sgirish 
25944961713Sgirish 	return (NXGE_OK);
26044961713Sgirish 
26144961713Sgirish }
26244961713Sgirish 
26344961713Sgirish /*
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:
271*86ef0a63SRichard Lowe  *	nxgep
272*86ef0a63SRichard Lowe  *	channel		The channel to initialize.
273678453a8Sspeer  *
274678453a8Sspeer  * NPI_NXGE function calls:
275678453a8Sspeer  *	nxge_init_fzc_rdc_pages()
276678453a8Sspeer  *
277678453a8Sspeer  * Context:
278678453a8Sspeer  *	Service Domain
27944961713Sgirish  */
28044961713Sgirish /*ARGSUSED*/
28144961713Sgirish 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)
28344961713Sgirish {
28444961713Sgirish 	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,
36352ccf843Smisaki 	    "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
36452ccf843Smisaki 	    red.bits.ldw.thre_sync,
36552ccf843Smisaki 	    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:
380*86ef0a63SRichard Lowe  *	nxgep
381*86ef0a63SRichard Lowe  *	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 
40044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_init_fzc_rxdma_channel"));
40144961713Sgirish 
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) {
40644961713Sgirish #ifndef	NIU_HV_WORKAROUND
40744961713Sgirish #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
40844961713Sgirish 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
40959ac0c16Sdavemq 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - call HV "
41059ac0c16Sdavemq 		    "set up logical pages"));
41144961713Sgirish 		/* Initialize the RXDMA logical pages */
41244961713Sgirish 		status = nxge_init_hv_fzc_rxdma_channel_pages(nxgep, channel,
413678453a8Sspeer 		    rbr_ring);
41444961713Sgirish 		if (status != NXGE_OK) {
41544961713Sgirish 			return (status);
41644961713Sgirish 		}
41744961713Sgirish #endif
41859ac0c16Sdavemq 		status = NXGE_OK;
41944961713Sgirish #else
42044961713Sgirish 		NXGE_DEBUG_MSG((nxgep, RX_CTL,
42159ac0c16Sdavemq 		    "==> nxge_init_fzc_rxdma_channel: N2_NIU - NEED to "
42259ac0c16Sdavemq 		    "set up logical pages"));
42344961713Sgirish 		/* Initialize the RXDMA logical pages */
42444961713Sgirish 		status = nxge_init_fzc_rxdma_channel_pages(nxgep, channel,
425678453a8Sspeer 		    rbr_ring);
42644961713Sgirish 		if (status != NXGE_OK) {
42744961713Sgirish 			return (status);
42844961713Sgirish 		}
42944961713Sgirish #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);
43944961713Sgirish 	}
44044961713Sgirish 
44144961713Sgirish 	/* Configure RED parameters */
442678453a8Sspeer 	status = nxge_init_fzc_rxdma_channel_red(nxgep, channel, rcr_ring);
44344961713Sgirish 
44444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_init_fzc_rxdma_channel"));
44544961713Sgirish 	return (status);
44644961713Sgirish }
44744961713Sgirish 
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:
457*86ef0a63SRichard Lowe  *	nxgep
458*86ef0a63SRichard Lowe  *	channel		The channel to initialize.
459*86ef0a63SRichard Lowe  *	page0		Logical page 0 definition.
460*86ef0a63SRichard Lowe  *	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,
48652ccf843Smisaki 	    "==> 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,
49152ccf843Smisaki 		    "<== nxge_init_fzc_rdc_pages: "
49252ccf843Smisaki 		    "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,
49852ccf843Smisaki 		    "<== nxge_init_fzc_rdc_pages: "
49952ccf843Smisaki 		    "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 
53144961713Sgirish /*ARGSUSED*/
53244961713Sgirish nxge_status_t
nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep,uint16_t channel,p_rx_rbr_ring_t rbrp)53344961713Sgirish nxge_init_fzc_rxdma_channel_pages(p_nxge_t nxgep,
534*86ef0a63SRichard Lowe     uint16_t channel, p_rx_rbr_ring_t rbrp)
53544961713Sgirish {
53644961713Sgirish 	npi_handle_t		handle;
53744961713Sgirish 	dma_log_page_t		cfg;
53844961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
53944961713Sgirish 
54044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
54152ccf843Smisaki 	    "==> nxge_init_fzc_rxdma_channel_pages"));
54244961713Sgirish 
54344961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
54444961713Sgirish 	/*
54544961713Sgirish 	 * Initialize logical page 1.
54644961713Sgirish 	 */
54744961713Sgirish 	cfg.func_num = nxgep->function_num;
54844961713Sgirish 	cfg.page_num = 0;
54944961713Sgirish 	cfg.valid = rbrp->page_valid.bits.ldw.page0;
55044961713Sgirish 	cfg.value = rbrp->page_value_1.value;
55144961713Sgirish 	cfg.mask = rbrp->page_mask_1.value;
55244961713Sgirish 	cfg.reloc = rbrp->page_reloc_1.value;
55344961713Sgirish 	rs = npi_rxdma_cfg_logical_page(handle, channel,
55452ccf843Smisaki 	    (p_dma_log_page_t)&cfg);
55544961713Sgirish 	if (rs != NPI_SUCCESS) {
55644961713Sgirish 		return (NXGE_ERROR | rs);
55744961713Sgirish 	}
55844961713Sgirish 
55944961713Sgirish 	/*
56044961713Sgirish 	 * Initialize logical page 2.
56144961713Sgirish 	 */
56244961713Sgirish 	cfg.page_num = 1;
56344961713Sgirish 	cfg.valid = rbrp->page_valid.bits.ldw.page1;
56444961713Sgirish 	cfg.value = rbrp->page_value_2.value;
56544961713Sgirish 	cfg.mask = rbrp->page_mask_2.value;
56644961713Sgirish 	cfg.reloc = rbrp->page_reloc_2.value;
56744961713Sgirish 
56844961713Sgirish 	rs = npi_rxdma_cfg_logical_page(handle, channel, &cfg);
56944961713Sgirish 	if (rs != NPI_SUCCESS) {
57044961713Sgirish 		return (NXGE_ERROR | rs);
57144961713Sgirish 	}
57244961713Sgirish 
57344961713Sgirish 	/* Initialize the page handle */
57444961713Sgirish 	rs = npi_rxdma_cfg_logical_page_handle(handle, channel,
57552ccf843Smisaki 	    rbrp->page_hdl.bits.ldw.handle);
57644961713Sgirish 
57744961713Sgirish 	if (rs != NPI_SUCCESS) {
57844961713Sgirish 		return (NXGE_ERROR | rs);
57944961713Sgirish 	}
58044961713Sgirish 
58144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
58252ccf843Smisaki 	    "<== nxge_init_fzc_rxdma_channel_pages"));
58344961713Sgirish 
58444961713Sgirish 	return (NXGE_OK);
58544961713Sgirish }
58644961713Sgirish 
58744961713Sgirish /*ARGSUSED*/
58844961713Sgirish nxge_status_t
nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep,uint16_t channel,p_rx_rcr_ring_t rcr_p)58944961713Sgirish nxge_init_fzc_rxdma_channel_red(p_nxge_t nxgep,
590*86ef0a63SRichard Lowe     uint16_t channel, p_rx_rcr_ring_t rcr_p)
59144961713Sgirish {
59244961713Sgirish 	npi_handle_t		handle;
59344961713Sgirish 	rdc_red_para_t		red;
59444961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
59544961713Sgirish 
59644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rxdma_channel_red"));
59744961713Sgirish 
59844961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
59944961713Sgirish 	red.value = 0;
60044961713Sgirish 	red.bits.ldw.win = RXDMA_RED_WINDOW_DEFAULT;
60144961713Sgirish 	red.bits.ldw.thre = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
60244961713Sgirish 	red.bits.ldw.win_syn = RXDMA_RED_WINDOW_DEFAULT;
60344961713Sgirish 	red.bits.ldw.thre_sync = (rcr_p->comp_size - RXDMA_RED_LESS_ENTRIES);
60444961713Sgirish 
60544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
60652ccf843Smisaki 	    "==> nxge_init_fzc_rxdma_channel_red(thre_sync %d(%x))",
60752ccf843Smisaki 	    red.bits.ldw.thre_sync,
60852ccf843Smisaki 	    red.bits.ldw.thre_sync));
60944961713Sgirish 
61044961713Sgirish 	rs = npi_rxdma_cfg_wred_param(handle, channel, &red);
61144961713Sgirish 	if (rs != NPI_SUCCESS) {
61244961713Sgirish 		return (NXGE_ERROR | rs);
61344961713Sgirish 	}
61444961713Sgirish 
61544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
61652ccf843Smisaki 	    "<== nxge_init_fzc_rxdma_channel_red"));
61744961713Sgirish 
61844961713Sgirish 	return (NXGE_OK);
61944961713Sgirish }
62044961713Sgirish 
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:
629*86ef0a63SRichard Lowe  *	nxgep
630*86ef0a63SRichard Lowe  *	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(
70252ccf843Smisaki 	    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 
70944961713Sgirish /*ARGSUSED*/
71044961713Sgirish 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)71144961713Sgirish nxge_init_fzc_txdma_channel(p_nxge_t nxgep, uint16_t channel,
712*86ef0a63SRichard Lowe     p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p)
71344961713Sgirish {
71444961713Sgirish 	nxge_status_t	status = NXGE_OK;
71544961713Sgirish 
71644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
71752ccf843Smisaki 	    "==> nxge_init_fzc_txdma_channel"));
71844961713Sgirish 
71959ac0c16Sdavemq 	if (nxgep->niu_type == N2_NIU) {
72044961713Sgirish #ifndef	NIU_HV_WORKAROUND
72144961713Sgirish #if	defined(sun4v) && defined(NIU_LP_WORKAROUND)
72244961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
72359ac0c16Sdavemq 		    "==> nxge_init_fzc_txdma_channel "
72459ac0c16Sdavemq 		    "N2_NIU: call HV to set up txdma logical pages"));
72544961713Sgirish 		status = nxge_init_hv_fzc_txdma_channel_pages(nxgep, channel,
72659ac0c16Sdavemq 		    tx_ring_p);
72744961713Sgirish 		if (status != NXGE_OK) {
72844961713Sgirish 			return (status);
72944961713Sgirish 		}
73044961713Sgirish #endif
73159ac0c16Sdavemq 		status = NXGE_OK;
73244961713Sgirish #else
73344961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
73459ac0c16Sdavemq 		    "==> nxge_init_fzc_txdma_channel "
73559ac0c16Sdavemq 		    "N2_NIU: NEED to set up txdma logical pages"));
73644961713Sgirish 		/* Initialize the TXDMA logical pages */
73744961713Sgirish 		(void) nxge_init_fzc_txdma_channel_pages(nxgep, channel,
73859ac0c16Sdavemq 		    tx_ring_p);
73944961713Sgirish #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);
74644961713Sgirish 	}
74744961713Sgirish 
74844961713Sgirish 	/*
74944961713Sgirish 	 * Configure Transmit DRR Weight parameters
75044961713Sgirish 	 * (It actually programs the TXC max burst register).
75144961713Sgirish 	 */
75244961713Sgirish 	(void) nxge_init_fzc_txdma_channel_drr(nxgep, channel, tx_ring_p);
75344961713Sgirish 
75444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
75552ccf843Smisaki 	    "<== nxge_init_fzc_txdma_channel"));
75644961713Sgirish 	return (status);
75744961713Sgirish }
75844961713Sgirish 
75944961713Sgirish 
76044961713Sgirish nxge_status_t
nxge_init_fzc_rx_common(p_nxge_t nxgep)76144961713Sgirish nxge_init_fzc_rx_common(p_nxge_t nxgep)
76244961713Sgirish {
76344961713Sgirish 	npi_handle_t	handle;
76444961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
76544961713Sgirish 	nxge_status_t	status = NXGE_OK;
7664ba491f5SMichael Speer 	nxge_rdc_grp_t	*rdc_grp_p;
76744961713Sgirish 	clock_t		lbolt;
768678453a8Sspeer 	int		table;
769678453a8Sspeer 
770678453a8Sspeer 	nxge_hw_pt_cfg_t *hardware;
77144961713Sgirish 
77244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL, "==> nxge_init_fzc_rx_common"));
77344961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
77444961713Sgirish 	if (!handle.regp) {
77544961713Sgirish 		NXGE_DEBUG_MSG((nxgep, DMA_CTL,
77652ccf843Smisaki 		    "==> nxge_init_fzc_rx_common null ptr"));
77744961713Sgirish 		return (NXGE_ERROR);
77844961713Sgirish 	}
77944961713Sgirish 
78044961713Sgirish 	/*
78144961713Sgirish 	 * Configure the rxdma clock divider
78244961713Sgirish 	 * This is the granularity counter based on
78344961713Sgirish 	 * the hardware system clock (i.e. 300 Mhz) and
78444961713Sgirish 	 * it is running around 3 nanoseconds.
78544961713Sgirish 	 * So, set the clock divider counter to 1000 to get
78644961713Sgirish 	 * microsecond granularity.
78744961713Sgirish 	 * For example, for a 3 microsecond timeout, the timeout
78844961713Sgirish 	 * will be set to 1.
78944961713Sgirish 	 */
79044961713Sgirish 	rs = npi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT);
79144961713Sgirish 	if (rs != NPI_SUCCESS)
79244961713Sgirish 		return (NXGE_ERROR | rs);
79344961713Sgirish 
79444961713Sgirish 
79544961713Sgirish 	/*
79644961713Sgirish 	 * Enable WRED and program an initial value.
79744961713Sgirish 	 * Use time to set the initial random number.
79844961713Sgirish 	 */
79944961713Sgirish 	(void) drv_getparm(LBOLT, &lbolt);
80044961713Sgirish 	rs = npi_rxdma_cfg_red_rand_init(handle, (uint16_t)lbolt);
80144961713Sgirish 	if (rs != NPI_SUCCESS)
80244961713Sgirish 		return (NXGE_ERROR | rs);
80344961713Sgirish 
804678453a8Sspeer 	hardware = &nxgep->pt_config.hw_config;
805678453a8Sspeer 	for (table = 0; table < NXGE_MAX_RDC_GRPS; table++) {
806678453a8Sspeer 		/* Does this table belong to <nxgep>? */
8074ba491f5SMichael Speer 		if (hardware->grpids[table] == (nxgep->function_num + 256)) {
8084ba491f5SMichael Speer 			rdc_grp_p = &nxgep->pt_config.rdc_grps[table];
8094ba491f5SMichael Speer 			status = nxge_init_fzc_rdc_tbl(nxgep, rdc_grp_p, table);
8104ba491f5SMichael Speer 		}
811678453a8Sspeer 	}
81244961713Sgirish 
81344961713Sgirish 	/* Ethernet Timeout Counter (?) */
81444961713Sgirish 
81544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, DMA_CTL,
81652ccf843Smisaki 	    "<== nxge_init_fzc_rx_common:status 0x%08x", status));
81744961713Sgirish 
81844961713Sgirish 	return (status);
81944961713Sgirish }
82044961713Sgirish 
82144961713Sgirish nxge_status_t
nxge_init_fzc_rdc_tbl(p_nxge_t nxge,nxge_rdc_grp_t * group,int rdc_tbl)8224ba491f5SMichael Speer nxge_init_fzc_rdc_tbl(p_nxge_t nxge, nxge_rdc_grp_t *group, int rdc_tbl)
82344961713Sgirish {
824678453a8Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
825678453a8Sspeer 	nx_rdc_tbl_t	*table;
826678453a8Sspeer 	npi_handle_t	handle;
82744961713Sgirish 
828678453a8Sspeer 	npi_status_t	rs = NPI_SUCCESS;
829678453a8Sspeer 	nxge_status_t	status = NXGE_OK;
83044961713Sgirish 
831678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_init_fzc_rdc_tbl(%d)", table));
832678453a8Sspeer 
833678453a8Sspeer 	/* This RDC table must have been previously bound to <nxge>. */
834678453a8Sspeer 	MUTEX_ENTER(&nhd->lock);
835678453a8Sspeer 	table = &nhd->rdc_tbl[rdc_tbl];
836678453a8Sspeer 	if (table->nxge != (uintptr_t)nxge) {
837678453a8Sspeer 		MUTEX_EXIT(&nhd->lock);
838678453a8Sspeer 		NXGE_ERROR_MSG((nxge, DMA_CTL,
839678453a8Sspeer 		    "nxge_init_fzc_rdc_tbl(%d): not owner", table));
840678453a8Sspeer 		return (NXGE_ERROR);
841678453a8Sspeer 	} else {
842678453a8Sspeer 		table->map = group->map;
843678453a8Sspeer 	}
844678453a8Sspeer 	MUTEX_EXIT(&nhd->lock);
845678453a8Sspeer 
846678453a8Sspeer 	handle = NXGE_DEV_NPI_HANDLE(nxge);
847678453a8Sspeer 
848678453a8Sspeer 	rs = npi_rxdma_rdc_table_config(handle, rdc_tbl,
849678453a8Sspeer 	    group->map, group->max_rdcs);
850678453a8Sspeer 
851678453a8Sspeer 	if (rs != NPI_SUCCESS) {
852678453a8Sspeer 		status = NXGE_ERROR | rs;
85344961713Sgirish 	}
85444961713Sgirish 
855678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "<== nxge_init_fzc_rdc_tbl(%d)", table));
85644961713Sgirish 	return (status);
85744961713Sgirish }
85844961713Sgirish 
859678453a8Sspeer static
860678453a8Sspeer int
rdc_tbl_bind(p_nxge_t nxge,int rdc_tbl)861678453a8Sspeer rdc_tbl_bind(p_nxge_t nxge, int rdc_tbl)
862678453a8Sspeer {
863678453a8Sspeer 	nxge_hio_data_t *nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
864678453a8Sspeer 	nx_rdc_tbl_t *table;
865678453a8Sspeer 	int i;
866678453a8Sspeer 
867678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, DMA_CTL, "==> nxge_fzc_rdc_tbl_bind"));
868678453a8Sspeer 
869678453a8Sspeer 	MUTEX_ENTER(&nhd->lock);
870678453a8Sspeer 	/* is the caller asking for a particular table? */
871678453a8Sspeer 	if (rdc_tbl >= 0 && rdc_tbl < NXGE_MAX_RDC_GROUPS) {
872678453a8Sspeer 		table = &nhd->rdc_tbl[rdc_tbl];
873678453a8Sspeer 		if (table->nxge == 0) {
874678453a8Sspeer 			table->nxge = (uintptr_t)nxge; /* It is now bound. */
875678453a8Sspeer 			NXGE_DEBUG_MSG((nxge, DMA_CTL,
876678453a8Sspeer 			    "<== nxge_fzc_rdc_tbl_bind(%d)", rdc_tbl));
877678453a8Sspeer 			MUTEX_EXIT(&nhd->lock);
878678453a8Sspeer 			return (rdc_tbl);
879678453a8Sspeer 		}
880678453a8Sspeer 	} else {	/* The caller will take any old RDC table. */
881678453a8Sspeer 		for (i = 0; i < NXGE_MAX_RDC_GROUPS; i++) {
882678453a8Sspeer 			nx_rdc_tbl_t *table = &nhd->rdc_tbl[i];
883678453a8Sspeer 			if (table->nxge == 0) {
884678453a8Sspeer 				table->nxge = (uintptr_t)nxge;
885678453a8Sspeer 				/* It is now bound. */
886678453a8Sspeer 				MUTEX_EXIT(&nhd->lock);
887678453a8Sspeer 				NXGE_DEBUG_MSG((nxge, DMA_CTL,
888678453a8Sspeer 				    "<== nxge_fzc_rdc_tbl_bind: %d", i));
889678453a8Sspeer 				return (i);
890678453a8Sspeer 			}
891678453a8Sspeer 		}
892678453a8Sspeer 	}
893678453a8Sspeer 	MUTEX_EXIT(&nhd->lock);
894678453a8Sspeer 
895678453a8Sspeer 	NXGE_DEBUG_MSG((nxge, HIO_CTL, "<== nxge_fzc_rdc_tbl_bind"));
896678453a8Sspeer 
897678453a8Sspeer 	return (-EBUSY);	/* RDC tables are bound. */
898678453a8Sspeer }
899678453a8Sspeer 
900678453a8Sspeer int
nxge_fzc_rdc_tbl_bind(nxge_t * nxge,int grp_index,int acceptNoSubstitutes)901678453a8Sspeer nxge_fzc_rdc_tbl_bind(
902678453a8Sspeer 	nxge_t *nxge,
903678453a8Sspeer 	int grp_index,
904678453a8Sspeer 	int acceptNoSubstitutes)
905678453a8Sspeer {
906678453a8Sspeer 	nxge_hw_pt_cfg_t *hardware;
907678453a8Sspeer 	int index;
908678453a8Sspeer 
909678453a8Sspeer 	hardware = &nxge->pt_config.hw_config;
910678453a8Sspeer 
911678453a8Sspeer 	if ((index = rdc_tbl_bind(nxge, grp_index)) < 0) {
912678453a8Sspeer 		if (acceptNoSubstitutes)
913678453a8Sspeer 			return (index);
914678453a8Sspeer 		index = rdc_tbl_bind(nxge, grp_index);
915678453a8Sspeer 		if (index < 0) {
916678453a8Sspeer 			NXGE_ERROR_MSG((nxge, OBP_CTL,
917678453a8Sspeer 			    "nxge_fzc_rdc_tbl_init: "
918678453a8Sspeer 			    "there are no free RDC tables!"));
919678453a8Sspeer 			return (index);
920678453a8Sspeer 		}
921678453a8Sspeer 	}
922678453a8Sspeer 
923678453a8Sspeer 	hardware->grpids[index] = nxge->function_num + 256;
924678453a8Sspeer 
925678453a8Sspeer 	return (index);
926678453a8Sspeer }
927