/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include /* * System interrupt registers that are under function zero management. */ hxge_status_t hxge_fzc_intr_init(p_hxge_t hxgep) { hxge_status_t status = HXGE_OK; HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_init")); /* Configure the initial timer resolution */ if ((status = hxge_fzc_intr_tmres_set(hxgep)) != HXGE_OK) { return (status); } /* * Set up the logical device group's logical devices that * the group owns. */ if ((status = hxge_fzc_intr_ldg_num_set(hxgep)) != HXGE_OK) { return (status); } /* Configure the system interrupt data */ if ((status = hxge_fzc_intr_sid_set(hxgep)) != HXGE_OK) { return (status); } HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_init")); return (status); } hxge_status_t hxge_fzc_intr_ldg_num_set(p_hxge_t hxgep) { p_hxge_ldg_t ldgp; p_hxge_ldv_t ldvp; hpi_handle_t handle; int i, j; hpi_status_t rs = HPI_SUCCESS; HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_ldg_num_set")); if (hxgep->ldgvp == NULL) { return (HXGE_ERROR); } ldgp = hxgep->ldgvp->ldgp; ldvp = hxgep->ldgvp->ldvp; if (ldgp == NULL || ldvp == NULL) { return (HXGE_ERROR); } handle = HXGE_DEV_HPI_HANDLE(hxgep); for (i = 0; i < hxgep->ldgvp->ldg_intrs; i++, ldgp++) { HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_ldg_num_set " "<== hxge_f(Hydra): # ldv %d in group %d", ldgp->nldvs, ldgp->ldg)); for (j = 0; j < ldgp->nldvs; j++, ldvp++) { rs = hpi_fzc_ldg_num_set(handle, ldvp->ldv, ldvp->ldg_assigned); if (rs != HPI_SUCCESS) { HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_ldg_num_set failed " " rs 0x%x ldv %d ldg %d", rs, ldvp->ldv, ldvp->ldg_assigned)); return (HXGE_ERROR | rs); } HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_ldg_num_set OK ldv %d ldg %d", ldvp->ldv, ldvp->ldg_assigned)); } } HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_ldg_num_set")); return (HXGE_OK); } hxge_status_t hxge_fzc_intr_tmres_set(p_hxge_t hxgep) { hpi_handle_t handle; hpi_status_t rs = HPI_SUCCESS; HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_tmrese_set")); if (hxgep->ldgvp == NULL) { return (HXGE_ERROR); } handle = HXGE_DEV_HPI_HANDLE(hxgep); if ((rs = hpi_fzc_ldg_timer_res_set(handle, hxgep->ldgvp->tmres))) { return (HXGE_ERROR | rs); } HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_tmrese_set")); return (HXGE_OK); } hxge_status_t hxge_fzc_intr_sid_set(p_hxge_t hxgep) { hpi_handle_t handle; p_hxge_ldg_t ldgp; fzc_sid_t sid; int i; hpi_status_t rs = HPI_SUCCESS; HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_sid_set")); if (hxgep->ldgvp == NULL) { HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_sid_set: no ldg")); return (HXGE_ERROR); } handle = HXGE_DEV_HPI_HANDLE(hxgep); ldgp = hxgep->ldgvp->ldgp; HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_sid_set: #int %d", hxgep->ldgvp->ldg_intrs)); for (i = 0; i < hxgep->ldgvp->ldg_intrs; i++, ldgp++) { sid.ldg = ldgp->ldg; sid.vector = ldgp->vector; HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_fzc_intr_sid_set(%d): group %d vector %d", i, sid.ldg, sid.vector)); rs = hpi_fzc_sid_set(handle, sid); if (rs != HPI_SUCCESS) { HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_sid_set:failed 0x%x", rs)); return (HXGE_ERROR | rs); } } HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_fzc_intr_sid_set")); return (HXGE_OK); } /* * Receive DMA registers that are under function zero management. */ /*ARGSUSED*/ hxge_status_t hxge_init_fzc_rxdma_channel(p_hxge_t hxgep, uint16_t channel, p_rx_rbr_ring_t rbr_p, p_rx_rcr_ring_t rcr_p, p_rx_mbox_t mbox_p) { hxge_status_t status = HXGE_OK; HXGE_DEBUG_MSG((hxgep, RX_CTL, "==> hxge_init_fzc_rxdma_channel")); /* Initialize the RXDMA logical pages */ status = hxge_init_fzc_rxdma_channel_pages(hxgep, channel, rbr_p); if (status != HXGE_OK) return (status); HXGE_DEBUG_MSG((hxgep, RX_CTL, "<== hxge_init_fzc_rxdma_channel")); return (status); } /*ARGSUSED*/ hxge_status_t hxge_init_fzc_rxdma_channel_pages(p_hxge_t hxgep, uint16_t channel, p_rx_rbr_ring_t rbrp) { hpi_handle_t handle; hpi_status_t rs = HPI_SUCCESS; HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_init_fzc_rxdma_channel_pages")); handle = HXGE_DEV_HPI_HANDLE(hxgep); /* Initialize the page handle */ rs = hpi_rxdma_cfg_logical_page_handle(handle, channel, rbrp->page_hdl.bits.handle); if (rs != HPI_SUCCESS) return (HXGE_ERROR | rs); HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_init_fzc_rxdma_channel_pages")); return (HXGE_OK); } /*ARGSUSED*/ hxge_status_t hxge_init_fzc_txdma_channel(p_hxge_t hxgep, uint16_t channel, p_tx_ring_t tx_ring_p, p_tx_mbox_t mbox_p) { hxge_status_t status = HXGE_OK; HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_init_fzc_txdma_channel")); /* Initialize the TXDMA logical pages */ (void) hxge_init_fzc_txdma_channel_pages(hxgep, channel, tx_ring_p); HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_init_fzc_txdma_channel")); return (status); } hxge_status_t hxge_init_fzc_rx_common(p_hxge_t hxgep) { hpi_handle_t handle; hpi_status_t rs = HPI_SUCCESS; hxge_status_t status = HXGE_OK; HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_init_fzc_rx_common")); handle = HXGE_DEV_HPI_HANDLE(hxgep); /* * Configure the rxdma clock divider * This is the granularity counter based on * the hardware system clock (i.e. 300 Mhz) and * it is running around 3 nanoseconds. * So, set the clock divider counter to 1000 to get * microsecond granularity. * For example, for a 3 microsecond timeout, the timeout * will be set to 1. */ rs = hpi_rxdma_cfg_clock_div_set(handle, RXDMA_CK_DIV_DEFAULT); if (rs != HPI_SUCCESS) return (HXGE_ERROR | rs); HXGE_DEBUG_MSG((hxgep, DMA_CTL, "<== hxge_init_fzc_rx_common:status 0x%08x", status)); return (status); } hxge_status_t hxge_init_fzc_txdma_channel_pages(p_hxge_t hxgep, uint16_t channel, p_tx_ring_t tx_ring_p) { hpi_handle_t handle; hpi_status_t rs = HPI_SUCCESS; HXGE_DEBUG_MSG((hxgep, DMA_CTL, "==> hxge_init_fzc_txdma_channel_pages")); handle = HXGE_DEV_HPI_HANDLE(hxgep); /* Initialize the page handle */ rs = hpi_txdma_log_page_handle_set(handle, channel, &tx_ring_p->page_hdl); if (rs == HPI_SUCCESS) return (HXGE_OK); else return (HXGE_ERROR | rs); } hxge_status_t hxge_fzc_sys_err_mask_set(p_hxge_t hxgep, boolean_t mask) { hpi_status_t rs = HPI_SUCCESS; hpi_handle_t handle; handle = HXGE_DEV_HPI_HANDLE(hxgep); rs = hpi_fzc_sys_err_mask_set(handle, mask); if (rs == HPI_SUCCESS) return (HXGE_OK); else return (HXGE_ERROR | rs); }