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