xref: /titanic_52/usr/src/uts/common/io/hxge/hpi_vir.c (revision fe930412c257f961ae67039de3b164b83717976a)
13dec9fcdSqs148142 /*
23dec9fcdSqs148142  * CDDL HEADER START
33dec9fcdSqs148142  *
43dec9fcdSqs148142  * The contents of this file are subject to the terms of the
53dec9fcdSqs148142  * Common Development and Distribution License (the "License").
63dec9fcdSqs148142  * You may not use this file except in compliance with the License.
73dec9fcdSqs148142  *
83dec9fcdSqs148142  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93dec9fcdSqs148142  * or http://www.opensolaris.org/os/licensing.
103dec9fcdSqs148142  * See the License for the specific language governing permissions
113dec9fcdSqs148142  * and limitations under the License.
123dec9fcdSqs148142  *
133dec9fcdSqs148142  * When distributing Covered Code, include this CDDL HEADER in each
143dec9fcdSqs148142  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153dec9fcdSqs148142  * If applicable, add the following below this CDDL HEADER, with the
163dec9fcdSqs148142  * fields enclosed by brackets "[]" replaced with your own identifying
173dec9fcdSqs148142  * information: Portions Copyright [yyyy] [name of copyright owner]
183dec9fcdSqs148142  *
193dec9fcdSqs148142  * CDDL HEADER END
203dec9fcdSqs148142  */
213dec9fcdSqs148142 /*
223dec9fcdSqs148142  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
233dec9fcdSqs148142  * Use is subject to license terms.
243dec9fcdSqs148142  */
253dec9fcdSqs148142 
263dec9fcdSqs148142 #pragma ident	"%Z%%M%	%I%	%E% SMI"
273dec9fcdSqs148142 
283dec9fcdSqs148142 #include <hpi_vir.h>
293dec9fcdSqs148142 #include <hxge_defs.h>
30*fe930412Sqs148142 #include <hxge_impl.h>
313dec9fcdSqs148142 
323dec9fcdSqs148142 /*
333dec9fcdSqs148142  * Set up a logical group number that a logical device belongs to.
343dec9fcdSqs148142  */
353dec9fcdSqs148142 hpi_status_t
363dec9fcdSqs148142 hpi_fzc_ldg_num_set(hpi_handle_t handle, uint8_t ld, uint8_t ldg)
373dec9fcdSqs148142 {
383dec9fcdSqs148142 	ld_grp_ctrl_t	gnum;
393dec9fcdSqs148142 
403dec9fcdSqs148142 	if (!LD_VALID(ld)) {
413dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
423dec9fcdSqs148142 		    " hpi_fzc_ldg_num_set ld <0x%x>", ld));
433dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_LD_INVALID(ld));
443dec9fcdSqs148142 	}
453dec9fcdSqs148142 
463dec9fcdSqs148142 	if (!LDG_VALID(ldg)) {
473dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
483dec9fcdSqs148142 		    " hpi_fzc_ldg_num_set ldg <0x%x>", ldg));
493dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_LDG_INVALID(ld));
503dec9fcdSqs148142 	}
513dec9fcdSqs148142 
523dec9fcdSqs148142 	gnum.value = 0;
533dec9fcdSqs148142 	gnum.bits.num = ldg;
543dec9fcdSqs148142 
553dec9fcdSqs148142 	HXGE_REG_WR32(handle, LD_GRP_CTRL + LD_NUM_OFFSET(ld), gnum.value);
563dec9fcdSqs148142 
573dec9fcdSqs148142 	return (HPI_SUCCESS);
583dec9fcdSqs148142 }
593dec9fcdSqs148142 
603dec9fcdSqs148142 /*
613dec9fcdSqs148142  * Get device state vectors.
623dec9fcdSqs148142  */
633dec9fcdSqs148142 hpi_status_t
643dec9fcdSqs148142 hpi_ldsv_ldfs_get(hpi_handle_t handle, uint8_t ldg, uint32_t *vector0_p,
653dec9fcdSqs148142     uint32_t *vector1_p)
663dec9fcdSqs148142 {
673dec9fcdSqs148142 	int	status;
683dec9fcdSqs148142 
693dec9fcdSqs148142 	if ((status = hpi_ldsv_get(handle, ldg, VECTOR0, vector0_p))) {
703dec9fcdSqs148142 		return (status);
713dec9fcdSqs148142 	}
723dec9fcdSqs148142 	if ((status = hpi_ldsv_get(handle, ldg, VECTOR1, vector1_p))) {
733dec9fcdSqs148142 		return (status);
743dec9fcdSqs148142 	}
753dec9fcdSqs148142 
763dec9fcdSqs148142 	return (HPI_SUCCESS);
773dec9fcdSqs148142 }
783dec9fcdSqs148142 
793dec9fcdSqs148142 /*
803dec9fcdSqs148142  * Get device state vectors.
813dec9fcdSqs148142  */
823dec9fcdSqs148142 hpi_status_t
833dec9fcdSqs148142 hpi_ldsv_get(hpi_handle_t handle, uint8_t ldg, ldsv_type_t vector,
843dec9fcdSqs148142     uint32_t *ldf_p)
853dec9fcdSqs148142 {
863dec9fcdSqs148142 	uint32_t	offset;
873dec9fcdSqs148142 
883dec9fcdSqs148142 	if (!LDG_VALID(ldg)) {
893dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
903dec9fcdSqs148142 		    " hpi_ldsv_get Invalid Input ldg <0x%x>", ldg));
913dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_LDG_INVALID(ldg));
923dec9fcdSqs148142 	}
933dec9fcdSqs148142 
943dec9fcdSqs148142 	switch (vector) {
953dec9fcdSqs148142 	case VECTOR0:
963dec9fcdSqs148142 		offset = LDSV0 + LDSV_OFFSET(ldg);
973dec9fcdSqs148142 		break;
983dec9fcdSqs148142 
993dec9fcdSqs148142 	case VECTOR1:
1003dec9fcdSqs148142 		offset = LDSV1 + LDSV_OFFSET(ldg);
1013dec9fcdSqs148142 		break;
1023dec9fcdSqs148142 
1033dec9fcdSqs148142 	default:
1043dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1053dec9fcdSqs148142 		    " hpi_ldsv_get Invalid Input: ldsv type <0x%x>", vector));
1063dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_LDSV_INVALID(vector));
1073dec9fcdSqs148142 	}
1083dec9fcdSqs148142 
1093dec9fcdSqs148142 	HXGE_REG_RD32(handle, offset, ldf_p);
1103dec9fcdSqs148142 
1113dec9fcdSqs148142 	return (HPI_SUCCESS);
1123dec9fcdSqs148142 }
1133dec9fcdSqs148142 
1143dec9fcdSqs148142 /*
1153dec9fcdSqs148142  * Set the mask bits for both ldf0 and ldf1.
1163dec9fcdSqs148142  */
1173dec9fcdSqs148142 hpi_status_t
1183dec9fcdSqs148142 hpi_intr_mask_set(hpi_handle_t handle, uint8_t ld, uint8_t ldf_mask)
1193dec9fcdSqs148142 {
1203dec9fcdSqs148142 	uint32_t	offset;
1213dec9fcdSqs148142 
1223dec9fcdSqs148142 	if (!LD_VALID(ld)) {
1233dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1243dec9fcdSqs148142 		    " hpi_intr_mask_set ld", ld));
1253dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_LD_INVALID(ld));
1263dec9fcdSqs148142 	}
1273dec9fcdSqs148142 
1283dec9fcdSqs148142 	ldf_mask &= LD_IM_MASK;
1293dec9fcdSqs148142 	offset = LDSV_OFFSET_MASK(ld);
1303dec9fcdSqs148142 
1313dec9fcdSqs148142 	HPI_DEBUG_MSG((handle.function, HPI_VIR_CTL,
1323dec9fcdSqs148142 	    "hpi_intr_mask_set: ld %d offset 0x%0x mask 0x%x",
1333dec9fcdSqs148142 	    ld, offset, ldf_mask));
1343dec9fcdSqs148142 
1353dec9fcdSqs148142 	HXGE_REG_WR32(handle, offset, (uint32_t)ldf_mask);
1363dec9fcdSqs148142 
1373dec9fcdSqs148142 	return (HPI_SUCCESS);
1383dec9fcdSqs148142 }
1393dec9fcdSqs148142 
1403dec9fcdSqs148142 /*
1413dec9fcdSqs148142  * Set interrupt timer and arm bit.
1423dec9fcdSqs148142  */
1433dec9fcdSqs148142 hpi_status_t
1443dec9fcdSqs148142 hpi_intr_ldg_mgmt_set(hpi_handle_t handle, uint8_t ldg, boolean_t arm,
1453dec9fcdSqs148142     uint8_t timer)
1463dec9fcdSqs148142 {
1473dec9fcdSqs148142 	ld_intr_mgmt_t	mgm;
1483dec9fcdSqs148142 
1493dec9fcdSqs148142 	if (!LDG_VALID(ldg)) {
1503dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1513dec9fcdSqs148142 		    " hpi_intr_ldg_mgmt_set Invalid Input: ldg <0x%x>", ldg));
1523dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_LDG_INVALID(ldg));
1533dec9fcdSqs148142 	}
1543dec9fcdSqs148142 
1553dec9fcdSqs148142 	if (!LD_INTTIMER_VALID(timer)) {
1563dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1573dec9fcdSqs148142 		    " hpi_intr_ldg_mgmt_set Invalid Input"
1583dec9fcdSqs148142 		    " timer <0x%x>", timer));
1593dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_INTM_TM_INVALID(ldg));
1603dec9fcdSqs148142 	}
1613dec9fcdSqs148142 
1623dec9fcdSqs148142 	if (arm) {
1633dec9fcdSqs148142 		mgm.bits.arm = 1;
1643dec9fcdSqs148142 	} else {
1653dec9fcdSqs148142 		HXGE_REG_RD32(handle, LD_INTR_MGMT + LDSV_OFFSET(ldg),
1663dec9fcdSqs148142 		    &mgm.value);
1673dec9fcdSqs148142 	}
1683dec9fcdSqs148142 
1693dec9fcdSqs148142 	mgm.bits.timer = timer;
1703dec9fcdSqs148142 	HXGE_REG_WR32(handle, LD_INTR_MGMT + LDSV_OFFSET(ldg), mgm.value);
1713dec9fcdSqs148142 
1723dec9fcdSqs148142 	HPI_DEBUG_MSG((handle.function, HPI_VIR_CTL,
1733dec9fcdSqs148142 	    " hpi_intr_ldg_mgmt_set: ldg %d reg offset 0x%x",
1743dec9fcdSqs148142 	    ldg, LD_INTR_MGMT + LDSV_OFFSET(ldg)));
1753dec9fcdSqs148142 
1763dec9fcdSqs148142 	return (HPI_SUCCESS);
1773dec9fcdSqs148142 }
1783dec9fcdSqs148142 
1793dec9fcdSqs148142 /*
1803dec9fcdSqs148142  * Set the timer resolution.
1813dec9fcdSqs148142  */
1823dec9fcdSqs148142 hpi_status_t
1833dec9fcdSqs148142 hpi_fzc_ldg_timer_res_set(hpi_handle_t handle, uint32_t res)
1843dec9fcdSqs148142 {
1853dec9fcdSqs148142 	ld_intr_tim_res_t	tm;
1863dec9fcdSqs148142 
1873dec9fcdSqs148142 	if (res > LDGTITMRES_RES_MASK) {
1883dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1893dec9fcdSqs148142 		    " hpi_fzc_ldg_timer_res_set Invalid Input: res <0x%x>",
1903dec9fcdSqs148142 		    res));
1913dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_TM_RES_INVALID);
1923dec9fcdSqs148142 	}
1933dec9fcdSqs148142 
1943dec9fcdSqs148142 	tm.value = 0;
1953dec9fcdSqs148142 	tm.bits.res = res;
1963dec9fcdSqs148142 
1973dec9fcdSqs148142 	HXGE_REG_WR32(handle, LD_INTR_TIM_RES, tm.value);
1983dec9fcdSqs148142 
1993dec9fcdSqs148142 	return (HPI_SUCCESS);
2003dec9fcdSqs148142 }
2013dec9fcdSqs148142 
2023dec9fcdSqs148142 /*
2033dec9fcdSqs148142  * Set the system interrupt data.
2043dec9fcdSqs148142  */
2053dec9fcdSqs148142 hpi_status_t
2063dec9fcdSqs148142 hpi_fzc_sid_set(hpi_handle_t handle, fzc_sid_t sid)
2073dec9fcdSqs148142 {
2083dec9fcdSqs148142 	sid_t	sd;
2093dec9fcdSqs148142 
2103dec9fcdSqs148142 	if (!LDG_VALID(sid.ldg)) {
2113dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2123dec9fcdSqs148142 		    " hpi_fzc_sid_set Invalid Input: ldg <0x%x>", sid.ldg));
2133dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_LDG_INVALID(sid.ldg));
2143dec9fcdSqs148142 	}
2153dec9fcdSqs148142 
2163dec9fcdSqs148142 	if (!SID_VECTOR_VALID(sid.vector)) {
2173dec9fcdSqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2183dec9fcdSqs148142 		    " hpi_fzc_sid_set Invalid Input: vector <0x%x>",
2193dec9fcdSqs148142 		    sid.vector));
2203dec9fcdSqs148142 
2213dec9fcdSqs148142 		return (HPI_FAILURE | HPI_VIR_SID_VEC_INVALID(sid.vector));
2223dec9fcdSqs148142 	}
2233dec9fcdSqs148142 
2243dec9fcdSqs148142 	sd.value = 0;
2253dec9fcdSqs148142 	sd.bits.data = sid.vector;
2263dec9fcdSqs148142 	HXGE_REG_WR32(handle,  SID + LDG_SID_OFFSET(sid.ldg), sd.value);
2273dec9fcdSqs148142 
2283dec9fcdSqs148142 	return (HPI_SUCCESS);
2293dec9fcdSqs148142 }
2303dec9fcdSqs148142 
2313dec9fcdSqs148142 /*
2323dec9fcdSqs148142  * Mask/Unmask the device error mask bits.
2333dec9fcdSqs148142  */
2343dec9fcdSqs148142 hpi_status_t
2353dec9fcdSqs148142 hpi_fzc_sys_err_mask_set(hpi_handle_t handle, boolean_t mask)
2363dec9fcdSqs148142 {
2373dec9fcdSqs148142 	dev_err_mask_t	dev_mask;
2383dec9fcdSqs148142 
2393dec9fcdSqs148142 	dev_mask.value = 0;
2403dec9fcdSqs148142 	if (mask) {
2413dec9fcdSqs148142 		dev_mask.bits.tdc_mask0 = 1;
2423dec9fcdSqs148142 		dev_mask.bits.rdc_mask0 = 1;
2433dec9fcdSqs148142 		dev_mask.bits.vnm_pio_mask1 = 1;
2443dec9fcdSqs148142 		dev_mask.bits.tdc_mask1 = 1;
2453dec9fcdSqs148142 		dev_mask.bits.rdc_mask1 = 1;
2463dec9fcdSqs148142 		dev_mask.bits.peu_mask1 = 1;
2473dec9fcdSqs148142 	}
2483dec9fcdSqs148142 
2493dec9fcdSqs148142 	HXGE_REG_WR32(handle, DEV_ERR_MASK, dev_mask.value);
2503dec9fcdSqs148142 	return (HPI_SUCCESS);
2513dec9fcdSqs148142 }
2523dec9fcdSqs148142 
2533dec9fcdSqs148142 /*
2543dec9fcdSqs148142  * Get the system error stats.
2553dec9fcdSqs148142  */
2563dec9fcdSqs148142 hpi_status_t
2573dec9fcdSqs148142 hpi_fzc_sys_err_stat_get(hpi_handle_t handle, dev_err_stat_t *statp)
2583dec9fcdSqs148142 {
2593dec9fcdSqs148142 	HXGE_REG_RD32(handle,  DEV_ERR_STAT, &statp->value);
2603dec9fcdSqs148142 	return (HPI_SUCCESS);
2613dec9fcdSqs148142 }
262