xref: /illumos-gate/usr/src/uts/common/io/hxge/hpi_rxdma.c (revision b83cd2c3)
13dec9fcdSqs /*
23dec9fcdSqs  * CDDL HEADER START
33dec9fcdSqs  *
43dec9fcdSqs  * The contents of this file are subject to the terms of the
53dec9fcdSqs  * Common Development and Distribution License (the "License").
63dec9fcdSqs  * You may not use this file except in compliance with the License.
73dec9fcdSqs  *
83dec9fcdSqs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93dec9fcdSqs  * or http://www.opensolaris.org/os/licensing.
103dec9fcdSqs  * See the License for the specific language governing permissions
113dec9fcdSqs  * and limitations under the License.
123dec9fcdSqs  *
133dec9fcdSqs  * When distributing Covered Code, include this CDDL HEADER in each
143dec9fcdSqs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153dec9fcdSqs  * If applicable, add the following below this CDDL HEADER, with the
163dec9fcdSqs  * fields enclosed by brackets "[]" replaced with your own identifying
173dec9fcdSqs  * information: Portions Copyright [yyyy] [name of copyright owner]
183dec9fcdSqs  *
193dec9fcdSqs  * CDDL HEADER END
203dec9fcdSqs  */
213dec9fcdSqs /*
223dec9fcdSqs  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
233dec9fcdSqs  * Use is subject to license terms.
243dec9fcdSqs  */
253dec9fcdSqs 
263dec9fcdSqs #include <hpi_rxdma.h>
273dec9fcdSqs #include <hxge_common.h>
28fe930412Sqs #include <hxge_impl.h>
293dec9fcdSqs 
303dec9fcdSqs #define	 RXDMA_RESET_TRY_COUNT	5
313dec9fcdSqs #define	 RXDMA_RESET_DELAY	5
323dec9fcdSqs 
333dec9fcdSqs #define	 RXDMA_OP_DISABLE	0
343dec9fcdSqs #define	 RXDMA_OP_ENABLE	1
353dec9fcdSqs #define	 RXDMA_OP_RESET		2
363dec9fcdSqs 
373dec9fcdSqs #define	 RCR_TIMEOUT_ENABLE	1
383dec9fcdSqs #define	 RCR_TIMEOUT_DISABLE	2
393dec9fcdSqs #define	 RCR_THRESHOLD		4
403dec9fcdSqs 
413dec9fcdSqs hpi_status_t
hpi_rxdma_cfg_logical_page_handle(hpi_handle_t handle,uint8_t rdc,uint64_t page_handle)423dec9fcdSqs hpi_rxdma_cfg_logical_page_handle(hpi_handle_t handle, uint8_t rdc,
433dec9fcdSqs     uint64_t page_handle)
443dec9fcdSqs {
453dec9fcdSqs 	rdc_page_handle_t page_hdl;
463dec9fcdSqs 
473dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(rdc)) {
483dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
493dec9fcdSqs 		    "rxdma_cfg_logical_page_handle"
503dec9fcdSqs 		    " Illegal RDC number %d \n", rdc));
513dec9fcdSqs 		return (HPI_RXDMA_RDC_INVALID);
523dec9fcdSqs 	}
533dec9fcdSqs 
543dec9fcdSqs 	page_hdl.value = 0;
553dec9fcdSqs 	page_hdl.bits.handle = (uint32_t)page_handle;
563dec9fcdSqs 
573dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_hdl.value);
583dec9fcdSqs 
593dec9fcdSqs 	return (HPI_SUCCESS);
603dec9fcdSqs }
613dec9fcdSqs 
62*069fd767SMichael Speer hpi_status_t
hpi_rxdma_cfg_rdc_wait_for_qst(hpi_handle_t handle,uint8_t rdc)63*069fd767SMichael Speer hpi_rxdma_cfg_rdc_wait_for_qst(hpi_handle_t handle, uint8_t rdc)
64*069fd767SMichael Speer {
65*069fd767SMichael Speer 	rdc_rx_cfg1_t	cfg;
66*069fd767SMichael Speer 	uint32_t	count = RXDMA_RESET_TRY_COUNT;
67*069fd767SMichael Speer 	uint32_t	delay_time = RXDMA_RESET_DELAY;
68*069fd767SMichael Speer 
69*069fd767SMichael Speer 	RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
70*069fd767SMichael Speer 
71*069fd767SMichael Speer 	while ((count--) && (cfg.bits.qst == 0)) {
72*069fd767SMichael Speer 		HXGE_DELAY(delay_time);
73*069fd767SMichael Speer 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
74*069fd767SMichael Speer 	}
75*069fd767SMichael Speer 
76*069fd767SMichael Speer 	if (cfg.bits.qst == 0)
77*069fd767SMichael Speer 		return (HPI_FAILURE);
78*069fd767SMichael Speer 
79*069fd767SMichael Speer 	return (HPI_SUCCESS);
80*069fd767SMichael Speer }
813dec9fcdSqs 
823dec9fcdSqs /* RX DMA functions */
833dec9fcdSqs static hpi_status_t
hpi_rxdma_cfg_rdc_ctl(hpi_handle_t handle,uint8_t rdc,uint8_t op)843dec9fcdSqs hpi_rxdma_cfg_rdc_ctl(hpi_handle_t handle, uint8_t rdc, uint8_t op)
853dec9fcdSqs {
863dec9fcdSqs 	rdc_rx_cfg1_t cfg;
873dec9fcdSqs 	uint32_t count = RXDMA_RESET_TRY_COUNT;
883dec9fcdSqs 	uint32_t delay_time = RXDMA_RESET_DELAY;
893dec9fcdSqs 	uint32_t error = HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RESET_ERR, rdc);
903dec9fcdSqs 
913dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(rdc)) {
923dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
933dec9fcdSqs 		    "hpi_rxdma_cfg_rdc_ctl Illegal RDC number %d \n", rdc));
943dec9fcdSqs 		return (HPI_RXDMA_RDC_INVALID);
953dec9fcdSqs 	}
963dec9fcdSqs 
973dec9fcdSqs 	switch (op) {
983dec9fcdSqs 	case RXDMA_OP_ENABLE:
993dec9fcdSqs 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1003dec9fcdSqs 		cfg.bits.enable = 1;
1013dec9fcdSqs 		RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value);
1023dec9fcdSqs 
1033dec9fcdSqs 		HXGE_DELAY(delay_time);
104*069fd767SMichael Speer 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1053dec9fcdSqs 
106*069fd767SMichael Speer 		while ((count--) && (cfg.bits.qst == 1)) {
107*069fd767SMichael Speer 			HXGE_DELAY(delay_time);
108*069fd767SMichael Speer 			RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
109*069fd767SMichael Speer 		}
110*069fd767SMichael Speer 		if (cfg.bits.qst == 1) {
111*069fd767SMichael Speer 			return (HPI_FAILURE);
112*069fd767SMichael Speer 		}
1133dec9fcdSqs 		break;
114*069fd767SMichael Speer 
1153dec9fcdSqs 	case RXDMA_OP_DISABLE:
1163dec9fcdSqs 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1173dec9fcdSqs 		cfg.bits.enable = 0;
1183dec9fcdSqs 		RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value);
1193dec9fcdSqs 
1203dec9fcdSqs 		HXGE_DELAY(delay_time);
121*069fd767SMichael Speer 		if (hpi_rxdma_cfg_rdc_wait_for_qst(handle,
122*069fd767SMichael Speer 		    rdc) != HPI_SUCCESS) {
1233dec9fcdSqs 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1243dec9fcdSqs 			    " hpi_rxdma_cfg_rdc_ctl"
1253dec9fcdSqs 			    " RXDMA_OP_DISABLE Failed for RDC %d \n",
1263dec9fcdSqs 			    rdc));
1273dec9fcdSqs 			return (error);
1283dec9fcdSqs 		}
1293dec9fcdSqs 		break;
130*069fd767SMichael Speer 
1313dec9fcdSqs 	case RXDMA_OP_RESET:
1323dec9fcdSqs 		cfg.value = 0;
1333dec9fcdSqs 		cfg.bits.reset = 1;
1343dec9fcdSqs 		RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value);
1353dec9fcdSqs 		HXGE_DELAY(delay_time);
1363dec9fcdSqs 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1373dec9fcdSqs 
1383dec9fcdSqs 		while ((count--) && (cfg.bits.qst == 0)) {
1393dec9fcdSqs 			HXGE_DELAY(delay_time);
1403dec9fcdSqs 			RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1413dec9fcdSqs 		}
1423dec9fcdSqs 		if (count == 0) {
1433dec9fcdSqs 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1443dec9fcdSqs 			    " hpi_rxdma_cfg_rdc_ctl"
1453dec9fcdSqs 			    " Reset Failed for RDC %d \n", rdc));
1463dec9fcdSqs 			return (error);
1473dec9fcdSqs 		}
1483dec9fcdSqs 		break;
149*069fd767SMichael Speer 
1503dec9fcdSqs 	default:
1513dec9fcdSqs 		return (HPI_RXDMA_SW_PARAM_ERROR);
1523dec9fcdSqs 	}
1533dec9fcdSqs 
1543dec9fcdSqs 	return (HPI_SUCCESS);
1553dec9fcdSqs }
1563dec9fcdSqs 
1573dec9fcdSqs hpi_status_t
hpi_rxdma_cfg_rdc_enable(hpi_handle_t handle,uint8_t rdc)1583dec9fcdSqs hpi_rxdma_cfg_rdc_enable(hpi_handle_t handle, uint8_t rdc)
1593dec9fcdSqs {
1603dec9fcdSqs 	return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_ENABLE));
1613dec9fcdSqs }
1623dec9fcdSqs 
1633dec9fcdSqs hpi_status_t
hpi_rxdma_cfg_rdc_disable(hpi_handle_t handle,uint8_t rdc)1643dec9fcdSqs hpi_rxdma_cfg_rdc_disable(hpi_handle_t handle, uint8_t rdc)
1653dec9fcdSqs {
1663dec9fcdSqs 	return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_DISABLE));
1673dec9fcdSqs }
1683dec9fcdSqs 
1693dec9fcdSqs hpi_status_t
hpi_rxdma_cfg_rdc_reset(hpi_handle_t handle,uint8_t rdc)1703dec9fcdSqs hpi_rxdma_cfg_rdc_reset(hpi_handle_t handle, uint8_t rdc)
1713dec9fcdSqs {
1723dec9fcdSqs 	return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_RESET));
1733dec9fcdSqs }
1743dec9fcdSqs 
1753dec9fcdSqs static hpi_status_t
hpi_rxdma_cfg_rdc_rcr_ctl(hpi_handle_t handle,uint8_t rdc,uint8_t op,uint16_t param)1763dec9fcdSqs hpi_rxdma_cfg_rdc_rcr_ctl(hpi_handle_t handle, uint8_t rdc,
1773dec9fcdSqs     uint8_t op, uint16_t param)
1783dec9fcdSqs {
1793dec9fcdSqs 	rdc_rcr_cfg_b_t rcr_cfgb;
1803dec9fcdSqs 
1813dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(rdc)) {
1823dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1833dec9fcdSqs 		    "rxdma_cfg_rdc_rcr_ctl Illegal RDC number %d \n", rdc));
1843dec9fcdSqs 		return (HPI_RXDMA_RDC_INVALID);
1853dec9fcdSqs 	}
1863dec9fcdSqs 
1873dec9fcdSqs 	RXDMA_REG_READ64(handle, RDC_RCR_CFG_B, rdc, &rcr_cfgb.value);
1883dec9fcdSqs 
1893dec9fcdSqs 	switch (op) {
1903dec9fcdSqs 	case RCR_TIMEOUT_ENABLE:
1913dec9fcdSqs 		rcr_cfgb.bits.timeout = (uint8_t)param;
1923dec9fcdSqs 		rcr_cfgb.bits.entout = 1;
1933dec9fcdSqs 		break;
1943dec9fcdSqs 
1953dec9fcdSqs 	case RCR_THRESHOLD:
1963dec9fcdSqs 		rcr_cfgb.bits.pthres = param;
1973dec9fcdSqs 		break;
1983dec9fcdSqs 
1993dec9fcdSqs 	case RCR_TIMEOUT_DISABLE:
2003dec9fcdSqs 		rcr_cfgb.bits.entout = 0;
2013dec9fcdSqs 		break;
2023dec9fcdSqs 
2033dec9fcdSqs 	default:
2043dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2053dec9fcdSqs 		    "rxdma_cfg_rdc_rcr_ctl Illegal opcode %x \n", op));
2063dec9fcdSqs 		return (HPI_RXDMA_OPCODE_INVALID(rdc));
2073dec9fcdSqs 	}
2083dec9fcdSqs 
2093dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value);
2103dec9fcdSqs 	return (HPI_SUCCESS);
2113dec9fcdSqs }
2123dec9fcdSqs 
2133dec9fcdSqs hpi_status_t
hpi_rxdma_cfg_rdc_rcr_threshold(hpi_handle_t handle,uint8_t rdc,uint16_t rcr_threshold)2143dec9fcdSqs hpi_rxdma_cfg_rdc_rcr_threshold(hpi_handle_t handle, uint8_t rdc,
2153dec9fcdSqs     uint16_t rcr_threshold)
2163dec9fcdSqs {
2173dec9fcdSqs 	return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc,
2183dec9fcdSqs 	    RCR_THRESHOLD, rcr_threshold));
2193dec9fcdSqs }
2203dec9fcdSqs 
2213dec9fcdSqs hpi_status_t
hpi_rxdma_cfg_rdc_rcr_timeout(hpi_handle_t handle,uint8_t rdc,uint8_t rcr_timeout)2223dec9fcdSqs hpi_rxdma_cfg_rdc_rcr_timeout(hpi_handle_t handle, uint8_t rdc,
2233dec9fcdSqs     uint8_t rcr_timeout)
2243dec9fcdSqs {
2253dec9fcdSqs 	return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc,
2263dec9fcdSqs 	    RCR_TIMEOUT_ENABLE, rcr_timeout));
2273dec9fcdSqs }
2283dec9fcdSqs 
2293dec9fcdSqs /*
2303dec9fcdSqs  * Configure The RDC channel Rcv Buffer Ring
2313dec9fcdSqs  */
2323dec9fcdSqs hpi_status_t
hpi_rxdma_cfg_rdc_ring(hpi_handle_t handle,uint8_t rdc,rdc_desc_cfg_t * rdc_desc_cfg)2333dec9fcdSqs hpi_rxdma_cfg_rdc_ring(hpi_handle_t handle, uint8_t rdc,
2343dec9fcdSqs     rdc_desc_cfg_t *rdc_desc_cfg)
2353dec9fcdSqs {
2363dec9fcdSqs 	rdc_rbr_cfg_a_t		cfga;
2373dec9fcdSqs 	rdc_rbr_cfg_b_t		cfgb;
2383dec9fcdSqs 	rdc_rx_cfg1_t		cfg1;
2393dec9fcdSqs 	rdc_rx_cfg2_t		cfg2;
2403dec9fcdSqs 	rdc_rcr_cfg_a_t		rcr_cfga;
2413dec9fcdSqs 	rdc_rcr_cfg_b_t		rcr_cfgb;
2423dec9fcdSqs 	rdc_page_handle_t	page_handle;
2433dec9fcdSqs 
2443dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(rdc)) {
2453dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2463dec9fcdSqs 		    "rxdma_cfg_rdc_ring Illegal RDC number %d \n", rdc));
2473dec9fcdSqs 		return (HPI_RXDMA_RDC_INVALID);
2483dec9fcdSqs 	}
2493dec9fcdSqs 
2503dec9fcdSqs 	cfga.value = 0;
2513dec9fcdSqs 	cfgb.value = 0;
2523dec9fcdSqs 	cfg1.value = 0;
2533dec9fcdSqs 	cfg2.value = 0;
2543dec9fcdSqs 	page_handle.value = 0;
2553dec9fcdSqs 
2563dec9fcdSqs 	if (rdc_desc_cfg->mbox_enable == 1) {
2573dec9fcdSqs 		cfg1.bits.mbaddr_h = (rdc_desc_cfg->mbox_addr >> 32) & 0xfff;
2583dec9fcdSqs 		cfg2.bits.mbaddr_l = ((rdc_desc_cfg->mbox_addr &
2593dec9fcdSqs 		    RXDMA_CFIG2_MBADDR_L_MASK) >> RXDMA_CFIG2_MBADDR_L_SHIFT);
2603dec9fcdSqs 
2613dec9fcdSqs 		/*
2623dec9fcdSqs 		 * Only after all the configurations are set, then
2633dec9fcdSqs 		 * enable the RDC or else configuration fatal error
2643dec9fcdSqs 		 * will be returned (especially if the Hypervisor
2653dec9fcdSqs 		 * set up the logical pages with non-zero values.
2663dec9fcdSqs 		 * This HPI function only sets up the configuration.
2673dec9fcdSqs 		 * Call the enable function to enable the RDMC!
2683dec9fcdSqs 		 */
2693dec9fcdSqs 	}
2703dec9fcdSqs 
2713dec9fcdSqs 	if (rdc_desc_cfg->full_hdr == 1)
2723dec9fcdSqs 		cfg2.bits.full_hdr = 1;
2733dec9fcdSqs 
2743dec9fcdSqs 	if (RXDMA_BUFF_OFFSET_VALID(rdc_desc_cfg->offset)) {
2753dec9fcdSqs 		cfg2.bits.offset = rdc_desc_cfg->offset;
2763dec9fcdSqs 	} else {
2773dec9fcdSqs 		cfg2.bits.offset = SW_OFFSET_NO_OFFSET;
2783dec9fcdSqs 	}
2793dec9fcdSqs 
2803dec9fcdSqs 	/* rbr config */
2813dec9fcdSqs 	cfga.value = (rdc_desc_cfg->rbr_addr &
2823dec9fcdSqs 	    (RBR_CFIG_A_STDADDR_MASK | RBR_CFIG_A_STDADDR_BASE_MASK));
2833dec9fcdSqs 
2843dec9fcdSqs 	/* The remaining 20 bits in the DMA address form the handle */
2853dec9fcdSqs 	page_handle.bits.handle = (rdc_desc_cfg->rbr_addr >> 44) && 0xfffff;
2863dec9fcdSqs 
2873dec9fcdSqs 	/*
2883dec9fcdSqs 	 * The RBR ring size must be multiple of 64.
2893dec9fcdSqs 	 */
2903dec9fcdSqs 	if ((rdc_desc_cfg->rbr_len < RBR_DEFAULT_MIN_LEN) ||
2913dec9fcdSqs 	    (rdc_desc_cfg->rbr_len > RBR_DEFAULT_MAX_LEN) ||
2923dec9fcdSqs 	    (rdc_desc_cfg->rbr_len % 64)) {
2933dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2943dec9fcdSqs 		    "hpi_rxdma_cfg_rdc_ring Illegal RBR Queue Length %d \n",
2953dec9fcdSqs 		    rdc_desc_cfg->rbr_len));
2963dec9fcdSqs 		return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RBRSZIE_INVALID, rdc));
2973dec9fcdSqs 	}
2983dec9fcdSqs 
2993dec9fcdSqs 	/*
3003dec9fcdSqs 	 * The lower 6 bits are hardcoded to 0 and the higher 10 bits are
3013dec9fcdSqs 	 * stored in len.
3023dec9fcdSqs 	 */
3033dec9fcdSqs 	cfga.bits.len = rdc_desc_cfg->rbr_len >> 6;
3043dec9fcdSqs 	HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL,
3053dec9fcdSqs 	    "hpi_rxdma_cfg_rdc_ring CFGA 0x%llx len %d (RBR LEN %d)\n",
3063dec9fcdSqs 	    cfga.value, cfga.bits.len, rdc_desc_cfg->rbr_len));
3073dec9fcdSqs 
3083dec9fcdSqs 	/*
3093dec9fcdSqs 	 * bksize is 1 bit
3103dec9fcdSqs 	 * Buffer Block Size. b0 - 4K; b1 - 8K.
3113dec9fcdSqs 	 */
3123dec9fcdSqs 	if (rdc_desc_cfg->page_size == SIZE_4KB)
3133dec9fcdSqs 		cfgb.bits.bksize = RBR_BKSIZE_4K;
3143dec9fcdSqs 	else if (rdc_desc_cfg->page_size == SIZE_8KB)
3153dec9fcdSqs 		cfgb.bits.bksize = RBR_BKSIZE_8K;
3163dec9fcdSqs 	else {
3173dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3183dec9fcdSqs 		    "rxdma_cfg_rdc_ring blksize: Illegal buffer size %d \n",
3193dec9fcdSqs 		    rdc_desc_cfg->page_size));
3203dec9fcdSqs 		return (HPI_RXDMA_BUFSZIE_INVALID);
3213dec9fcdSqs 	}
3223dec9fcdSqs 
3233dec9fcdSqs 	/*
3243dec9fcdSqs 	 * Size 0 of packet buffer. b00 - 256; b01 - 512; b10 - 1K; b11 - resvd.
3253dec9fcdSqs 	 */
3263dec9fcdSqs 	if (rdc_desc_cfg->valid0) {
3273dec9fcdSqs 		if (rdc_desc_cfg->size0 == SIZE_256B)
3283dec9fcdSqs 			cfgb.bits.bufsz0 = RBR_BUFSZ0_256B;
3293dec9fcdSqs 		else if (rdc_desc_cfg->size0 == SIZE_512B)
3303dec9fcdSqs 			cfgb.bits.bufsz0 = RBR_BUFSZ0_512B;
3313dec9fcdSqs 		else if (rdc_desc_cfg->size0 == SIZE_1KB)
3323dec9fcdSqs 			cfgb.bits.bufsz0 = RBR_BUFSZ0_1K;
3333dec9fcdSqs 		else {
3343dec9fcdSqs 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3353dec9fcdSqs 			    " rxdma_cfg_rdc_ring"
3363dec9fcdSqs 			    " blksize0: Illegal buffer size %x \n",
3373dec9fcdSqs 			    rdc_desc_cfg->size0));
3383dec9fcdSqs 			return (HPI_RXDMA_BUFSZIE_INVALID);
3393dec9fcdSqs 		}
3403dec9fcdSqs 		cfgb.bits.vld0 = 1;
3413dec9fcdSqs 	} else {
3423dec9fcdSqs 		cfgb.bits.vld0 = 0;
3433dec9fcdSqs 	}
3443dec9fcdSqs 
3453dec9fcdSqs 	/*
3463dec9fcdSqs 	 * Size 1 of packet buffer. b0 - 1K; b1 - 2K.
3473dec9fcdSqs 	 */
3483dec9fcdSqs 	if (rdc_desc_cfg->valid1) {
3493dec9fcdSqs 		if (rdc_desc_cfg->size1 == SIZE_1KB)
3503dec9fcdSqs 			cfgb.bits.bufsz1 = RBR_BUFSZ1_1K;
3513dec9fcdSqs 		else if (rdc_desc_cfg->size1 == SIZE_2KB)
3523dec9fcdSqs 			cfgb.bits.bufsz1 = RBR_BUFSZ1_2K;
3533dec9fcdSqs 		else {
3543dec9fcdSqs 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3553dec9fcdSqs 			    " rxdma_cfg_rdc_ring"
3563dec9fcdSqs 			    " blksize1: Illegal buffer size %x \n",
3573dec9fcdSqs 			    rdc_desc_cfg->size1));
3583dec9fcdSqs 			return (HPI_RXDMA_BUFSZIE_INVALID);
3593dec9fcdSqs 		}
3603dec9fcdSqs 		cfgb.bits.vld1 = 1;
3613dec9fcdSqs 	} else {
3623dec9fcdSqs 		cfgb.bits.vld1 = 0;
3633dec9fcdSqs 	}
3643dec9fcdSqs 
3653dec9fcdSqs 	/*
3663dec9fcdSqs 	 * Size 2 of packet buffer. b0 - 2K; b1 - 4K.
3673dec9fcdSqs 	 */
3683dec9fcdSqs 	if (rdc_desc_cfg->valid2) {
3693dec9fcdSqs 		if (rdc_desc_cfg->size2 == SIZE_2KB)
3703dec9fcdSqs 			cfgb.bits.bufsz2 = RBR_BUFSZ2_2K;
3713dec9fcdSqs 		else if (rdc_desc_cfg->size2 == SIZE_4KB)
3723dec9fcdSqs 			cfgb.bits.bufsz2 = RBR_BUFSZ2_4K;
3733dec9fcdSqs 		else {
3743dec9fcdSqs 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3753dec9fcdSqs 			    " rxdma_cfg_rdc_ring"
3763dec9fcdSqs 			    " blksize2: Illegal buffer size %x \n",
3773dec9fcdSqs 			    rdc_desc_cfg->size2));
3783dec9fcdSqs 			return (HPI_RXDMA_BUFSZIE_INVALID);
3793dec9fcdSqs 		}
3803dec9fcdSqs 		cfgb.bits.vld2 = 1;
3813dec9fcdSqs 	} else {
3823dec9fcdSqs 		cfgb.bits.vld2 = 0;
3833dec9fcdSqs 	}
3843dec9fcdSqs 
3853dec9fcdSqs 	rcr_cfga.value = (rdc_desc_cfg->rcr_addr &
3863dec9fcdSqs 	    (RCRCFIG_A_STADDR_MASK | RCRCFIG_A_STADDR_BASE_MASK));
3873dec9fcdSqs 
3883dec9fcdSqs 	/*
3893dec9fcdSqs 	 * The rcr len must be multiple of 32.
3903dec9fcdSqs 	 */
3913dec9fcdSqs 	if ((rdc_desc_cfg->rcr_len < RCR_DEFAULT_MIN_LEN) ||
3923dec9fcdSqs 	    (rdc_desc_cfg->rcr_len > HXGE_RCR_MAX) ||
3933dec9fcdSqs 	    (rdc_desc_cfg->rcr_len % 32)) {
3943dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3953dec9fcdSqs 		    " rxdma_cfg_rdc_ring Illegal RCR Queue Length %d \n",
3963dec9fcdSqs 		    rdc_desc_cfg->rcr_len));
3973dec9fcdSqs 		return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RCRSZIE_INVALID, rdc));
3983dec9fcdSqs 	}
3993dec9fcdSqs 
4003dec9fcdSqs 	/*
4013dec9fcdSqs 	 * Bits 15:5 of the maximum number of 8B entries in RCR.  Bits 4:0 are
4023dec9fcdSqs 	 * hard-coded to zero.  The maximum size is 2^16 - 32.
4033dec9fcdSqs 	 */
4043dec9fcdSqs 	rcr_cfga.bits.len = rdc_desc_cfg->rcr_len >> 5;
4053dec9fcdSqs 
4063dec9fcdSqs 	rcr_cfgb.value = 0;
4073dec9fcdSqs 	if (rdc_desc_cfg->rcr_timeout_enable == 1) {
4083dec9fcdSqs 		/* check if the rcr timeout value is valid */
4093dec9fcdSqs 
4103dec9fcdSqs 		if (RXDMA_RCR_TO_VALID(rdc_desc_cfg->rcr_timeout)) {
4113dec9fcdSqs 			rcr_cfgb.bits.timeout = rdc_desc_cfg->rcr_timeout;
4123dec9fcdSqs 			rcr_cfgb.bits.entout = 1;
4133dec9fcdSqs 		} else {
4143dec9fcdSqs 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
4153dec9fcdSqs 			    " rxdma_cfg_rdc_ring"
4163dec9fcdSqs 			    " Illegal RCR Timeout value %d \n",
4173dec9fcdSqs 			    rdc_desc_cfg->rcr_timeout));
4183dec9fcdSqs 			rcr_cfgb.bits.entout = 0;
4193dec9fcdSqs 		}
4203dec9fcdSqs 	} else {
4213dec9fcdSqs 		rcr_cfgb.bits.entout = 0;
4223dec9fcdSqs 	}
4233dec9fcdSqs 
4243dec9fcdSqs 	/* check if the rcr threshold value is valid */
4253dec9fcdSqs 	if (RXDMA_RCR_THRESH_VALID(rdc_desc_cfg->rcr_threshold)) {
4263dec9fcdSqs 		rcr_cfgb.bits.pthres = rdc_desc_cfg->rcr_threshold;
4273dec9fcdSqs 	} else {
4283dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
4293dec9fcdSqs 		    " rxdma_cfg_rdc_ring Illegal RCR Threshold value %d \n",
4303dec9fcdSqs 		    rdc_desc_cfg->rcr_threshold));
4313dec9fcdSqs 		rcr_cfgb.bits.pthres = 1;
4323dec9fcdSqs 	}
4333dec9fcdSqs 
4343dec9fcdSqs 	/* now do the actual HW configuration */
4353dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg1.value);
4363dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_RX_CFG2, rdc, cfg2.value);
4373dec9fcdSqs 
4383dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_A, rdc, cfga.value);
4393dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_B, rdc, cfgb.value);
4403dec9fcdSqs 
4413dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_A, rdc, rcr_cfga.value);
4423dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value);
4433dec9fcdSqs 
4443dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_handle.value);
4453dec9fcdSqs 
4463dec9fcdSqs 	return (HPI_SUCCESS);
4473dec9fcdSqs }
4483dec9fcdSqs 
4493dec9fcdSqs hpi_status_t
hpi_rxdma_ring_perr_stat_get(hpi_handle_t handle,rdc_pref_par_log_t * pre_log,rdc_pref_par_log_t * sha_log)4503dec9fcdSqs hpi_rxdma_ring_perr_stat_get(hpi_handle_t handle,
4513dec9fcdSqs     rdc_pref_par_log_t *pre_log, rdc_pref_par_log_t *sha_log)
4523dec9fcdSqs {
4533dec9fcdSqs 	/*
4543dec9fcdSqs 	 * Hydra doesn't have details about these errors.
4553dec9fcdSqs 	 * It only provides the addresses of the errors.
4563dec9fcdSqs 	 */
4573dec9fcdSqs 	HXGE_REG_RD64(handle, RDC_PREF_PAR_LOG, &pre_log->value);
4583dec9fcdSqs 	HXGE_REG_RD64(handle, RDC_SHADOW_PAR_LOG, &sha_log->value);
4593dec9fcdSqs 
4603dec9fcdSqs 	return (HPI_SUCCESS);
4613dec9fcdSqs }
4623dec9fcdSqs 
4633dec9fcdSqs 
4643dec9fcdSqs /* system wide conf functions */
4653dec9fcdSqs 
4663dec9fcdSqs hpi_status_t
hpi_rxdma_cfg_clock_div_set(hpi_handle_t handle,uint16_t count)4673dec9fcdSqs hpi_rxdma_cfg_clock_div_set(hpi_handle_t handle, uint16_t count)
4683dec9fcdSqs {
4693dec9fcdSqs 	uint64_t	offset;
4703dec9fcdSqs 	rdc_clock_div_t	clk_div;
4713dec9fcdSqs 
4723dec9fcdSqs 	offset = RDC_CLOCK_DIV;
4733dec9fcdSqs 
4743dec9fcdSqs 	clk_div.value = 0;
4753dec9fcdSqs 	clk_div.bits.count = count;
4763dec9fcdSqs 	HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL,
4773dec9fcdSqs 	    " hpi_rxdma_cfg_clock_div_set: add 0x%llx "
4783dec9fcdSqs 	    "handle 0x%llx value 0x%llx",
4793dec9fcdSqs 	    handle.regp, handle.regh, clk_div.value));
4803dec9fcdSqs 
4813dec9fcdSqs 	HXGE_REG_WR64(handle, offset, clk_div.value);
4823dec9fcdSqs 
4833dec9fcdSqs 	return (HPI_SUCCESS);
4843dec9fcdSqs }
4853dec9fcdSqs 
4863dec9fcdSqs 
4873dec9fcdSqs hpi_status_t
hpi_rxdma_rdc_rbr_stat_get(hpi_handle_t handle,uint8_t rdc,rdc_rbr_qlen_t * rbr_stat)4883dec9fcdSqs hpi_rxdma_rdc_rbr_stat_get(hpi_handle_t handle, uint8_t rdc,
4893dec9fcdSqs     rdc_rbr_qlen_t *rbr_stat)
4903dec9fcdSqs {
4913dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(rdc)) {
4923dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
4933dec9fcdSqs 		    " rxdma_rdc_rbr_stat_get Illegal RDC Number %d \n", rdc));
4943dec9fcdSqs 		return (HPI_RXDMA_RDC_INVALID);
4953dec9fcdSqs 	}
4963dec9fcdSqs 
4973dec9fcdSqs 	RXDMA_REG_READ64(handle, RDC_RBR_QLEN, rdc, &rbr_stat->value);
4983dec9fcdSqs 	return (HPI_SUCCESS);
4993dec9fcdSqs }
5003dec9fcdSqs 
5013dec9fcdSqs 
5023dec9fcdSqs hpi_status_t
hpi_rxdma_rdc_rcr_qlen_get(hpi_handle_t handle,uint8_t rdc,uint16_t * rcr_qlen)5033dec9fcdSqs hpi_rxdma_rdc_rcr_qlen_get(hpi_handle_t handle, uint8_t rdc,
5043dec9fcdSqs     uint16_t *rcr_qlen)
5053dec9fcdSqs {
5063dec9fcdSqs 	rdc_rcr_qlen_t stats;
5073dec9fcdSqs 
5083dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(rdc)) {
5093dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5103dec9fcdSqs 		    " rxdma_rdc_rcr_qlen_get Illegal RDC Number %d \n", rdc));
5113dec9fcdSqs 		return (HPI_RXDMA_RDC_INVALID);
5123dec9fcdSqs 	}
5133dec9fcdSqs 
5143dec9fcdSqs 	RXDMA_REG_READ64(handle, RDC_RCR_QLEN, rdc, &stats.value);
5153dec9fcdSqs 	*rcr_qlen =  stats.bits.qlen;
5163dec9fcdSqs 	HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL,
5173dec9fcdSqs 	    " rxdma_rdc_rcr_qlen_get RDC %d qlen %x qlen %x\n",
5183dec9fcdSqs 	    rdc, *rcr_qlen, stats.bits.qlen));
5193dec9fcdSqs 	return (HPI_SUCCESS);
5203dec9fcdSqs }
5213dec9fcdSqs 
5223dec9fcdSqs hpi_status_t
hpi_rxdma_channel_rbr_empty_clear(hpi_handle_t handle,uint8_t channel)5233dec9fcdSqs hpi_rxdma_channel_rbr_empty_clear(hpi_handle_t handle, uint8_t channel)
5243dec9fcdSqs {
5253dec9fcdSqs 	rdc_stat_t	cs;
5263dec9fcdSqs 
5273dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(channel)) {
5283dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5293dec9fcdSqs 		    " hpi_rxdma_channel_rbr_empty_clear", " channel", channel));
5303dec9fcdSqs 		return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel));
5313dec9fcdSqs 	}
5323dec9fcdSqs 
5333dec9fcdSqs 	RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value);
5343dec9fcdSqs 	cs.bits.rbr_empty = 1;
5353dec9fcdSqs 	RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value);
5363dec9fcdSqs 
5373dec9fcdSqs 	return (HPI_SUCCESS);
5383dec9fcdSqs }
5393dec9fcdSqs 
5403dec9fcdSqs /*
5413dec9fcdSqs  * This function is called to operate on the control and status register.
5423dec9fcdSqs  */
5433dec9fcdSqs hpi_status_t
hpi_rxdma_control_status(hpi_handle_t handle,io_op_t op_mode,uint8_t channel,rdc_stat_t * cs_p)5443dec9fcdSqs hpi_rxdma_control_status(hpi_handle_t handle, io_op_t op_mode, uint8_t channel,
5453dec9fcdSqs     rdc_stat_t *cs_p)
5463dec9fcdSqs {
5473dec9fcdSqs 	int		status = HPI_SUCCESS;
5483dec9fcdSqs 	rdc_stat_t	cs;
5493dec9fcdSqs 
5503dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(channel)) {
5513dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5523dec9fcdSqs 		    "hpi_rxdma_control_status", "channel", channel));
5533dec9fcdSqs 		return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel));
5543dec9fcdSqs 	}
5553dec9fcdSqs 
5563dec9fcdSqs 	switch (op_mode) {
5573dec9fcdSqs 	case OP_GET:
5583dec9fcdSqs 		RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs_p->value);
5593dec9fcdSqs 		break;
5603dec9fcdSqs 
5613dec9fcdSqs 	case OP_SET:
5623dec9fcdSqs 		RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs_p->value);
5633dec9fcdSqs 		break;
5643dec9fcdSqs 
5653dec9fcdSqs 	case OP_UPDATE:
5663dec9fcdSqs 		RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value);
5673dec9fcdSqs 		RXDMA_REG_WRITE64(handle, RDC_STAT, channel,
5683dec9fcdSqs 		    cs_p->value | cs.value);
5693dec9fcdSqs 		break;
5703dec9fcdSqs 
5713dec9fcdSqs 	default:
5723dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5733dec9fcdSqs 		    "hpi_rxdma_control_status", "control", op_mode));
5743dec9fcdSqs 		return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel));
5753dec9fcdSqs 	}
5763dec9fcdSqs 
5773dec9fcdSqs 	return (status);
5783dec9fcdSqs }
5793dec9fcdSqs 
5803dec9fcdSqs /*
5813dec9fcdSqs  * This function is called to operate on the event mask
5823dec9fcdSqs  * register which is used for generating interrupts.
5833dec9fcdSqs  */
5843dec9fcdSqs hpi_status_t
hpi_rxdma_event_mask(hpi_handle_t handle,io_op_t op_mode,uint8_t channel,rdc_int_mask_t * mask_p)5853dec9fcdSqs hpi_rxdma_event_mask(hpi_handle_t handle, io_op_t op_mode, uint8_t channel,
5863dec9fcdSqs     rdc_int_mask_t *mask_p)
5873dec9fcdSqs {
5883dec9fcdSqs 	int		status = HPI_SUCCESS;
5893dec9fcdSqs 	rdc_int_mask_t	mask;
5903dec9fcdSqs 
5913dec9fcdSqs 	if (!RXDMA_CHANNEL_VALID(channel)) {
5923dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5933dec9fcdSqs 		    "hpi_rxdma_event_mask", "channel", channel));
5943dec9fcdSqs 		return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel));
5953dec9fcdSqs 	}
5963dec9fcdSqs 
5973dec9fcdSqs 	switch (op_mode) {
5983dec9fcdSqs 	case OP_GET:
5993dec9fcdSqs 		RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask_p->value);
6003dec9fcdSqs 		break;
6013dec9fcdSqs 
6023dec9fcdSqs 	case OP_SET:
6033dec9fcdSqs 		RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel, mask_p->value);
6043dec9fcdSqs 		break;
6053dec9fcdSqs 
6063dec9fcdSqs 	case OP_UPDATE:
6073dec9fcdSqs 		RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask.value);
6083dec9fcdSqs 		RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel,
6093dec9fcdSqs 		    mask_p->value | mask.value);
6103dec9fcdSqs 		break;
6113dec9fcdSqs 
6123dec9fcdSqs 	default:
6133dec9fcdSqs 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
6143dec9fcdSqs 		    "hpi_rxdma_event_mask", "eventmask", op_mode));
6153dec9fcdSqs 		return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel));
6163dec9fcdSqs 	}
6173dec9fcdSqs 
6183dec9fcdSqs 	return (status);
6193dec9fcdSqs }
620