xref: /onnv-gate/usr/src/uts/common/io/hxge/hpi_rxdma.c (revision 8141:500300f249ed)
16349Sqs148142 /*
26349Sqs148142  * CDDL HEADER START
36349Sqs148142  *
46349Sqs148142  * The contents of this file are subject to the terms of the
56349Sqs148142  * Common Development and Distribution License (the "License").
66349Sqs148142  * You may not use this file except in compliance with the License.
76349Sqs148142  *
86349Sqs148142  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96349Sqs148142  * or http://www.opensolaris.org/os/licensing.
106349Sqs148142  * See the License for the specific language governing permissions
116349Sqs148142  * and limitations under the License.
126349Sqs148142  *
136349Sqs148142  * When distributing Covered Code, include this CDDL HEADER in each
146349Sqs148142  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156349Sqs148142  * If applicable, add the following below this CDDL HEADER, with the
166349Sqs148142  * fields enclosed by brackets "[]" replaced with your own identifying
176349Sqs148142  * information: Portions Copyright [yyyy] [name of copyright owner]
186349Sqs148142  *
196349Sqs148142  * CDDL HEADER END
206349Sqs148142  */
216349Sqs148142 /*
226349Sqs148142  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
236349Sqs148142  * Use is subject to license terms.
246349Sqs148142  */
256349Sqs148142 
266349Sqs148142 #include <hpi_rxdma.h>
276349Sqs148142 #include <hxge_common.h>
286864Sqs148142 #include <hxge_impl.h>
296349Sqs148142 
306349Sqs148142 #define	 RXDMA_RESET_TRY_COUNT	5
316349Sqs148142 #define	 RXDMA_RESET_DELAY	5
326349Sqs148142 
336349Sqs148142 #define	 RXDMA_OP_DISABLE	0
346349Sqs148142 #define	 RXDMA_OP_ENABLE	1
356349Sqs148142 #define	 RXDMA_OP_RESET		2
366349Sqs148142 
376349Sqs148142 #define	 RCR_TIMEOUT_ENABLE	1
386349Sqs148142 #define	 RCR_TIMEOUT_DISABLE	2
396349Sqs148142 #define	 RCR_THRESHOLD		4
406349Sqs148142 
416349Sqs148142 hpi_status_t
hpi_rxdma_cfg_logical_page_handle(hpi_handle_t handle,uint8_t rdc,uint64_t page_handle)426349Sqs148142 hpi_rxdma_cfg_logical_page_handle(hpi_handle_t handle, uint8_t rdc,
436349Sqs148142     uint64_t page_handle)
446349Sqs148142 {
456349Sqs148142 	rdc_page_handle_t page_hdl;
466349Sqs148142 
476349Sqs148142 	if (!RXDMA_CHANNEL_VALID(rdc)) {
486349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
496349Sqs148142 		    "rxdma_cfg_logical_page_handle"
506349Sqs148142 		    " Illegal RDC number %d \n", rdc));
516349Sqs148142 		return (HPI_RXDMA_RDC_INVALID);
526349Sqs148142 	}
536349Sqs148142 
546349Sqs148142 	page_hdl.value = 0;
556349Sqs148142 	page_hdl.bits.handle = (uint32_t)page_handle;
566349Sqs148142 
576349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_hdl.value);
586349Sqs148142 
596349Sqs148142 	return (HPI_SUCCESS);
606349Sqs148142 }
616349Sqs148142 
62*7959SMichael.Speer@Sun.COM hpi_status_t
hpi_rxdma_cfg_rdc_wait_for_qst(hpi_handle_t handle,uint8_t rdc)63*7959SMichael.Speer@Sun.COM hpi_rxdma_cfg_rdc_wait_for_qst(hpi_handle_t handle, uint8_t rdc)
64*7959SMichael.Speer@Sun.COM {
65*7959SMichael.Speer@Sun.COM 	rdc_rx_cfg1_t	cfg;
66*7959SMichael.Speer@Sun.COM 	uint32_t	count = RXDMA_RESET_TRY_COUNT;
67*7959SMichael.Speer@Sun.COM 	uint32_t	delay_time = RXDMA_RESET_DELAY;
68*7959SMichael.Speer@Sun.COM 
69*7959SMichael.Speer@Sun.COM 	RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
70*7959SMichael.Speer@Sun.COM 
71*7959SMichael.Speer@Sun.COM 	while ((count--) && (cfg.bits.qst == 0)) {
72*7959SMichael.Speer@Sun.COM 		HXGE_DELAY(delay_time);
73*7959SMichael.Speer@Sun.COM 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
74*7959SMichael.Speer@Sun.COM 	}
75*7959SMichael.Speer@Sun.COM 
76*7959SMichael.Speer@Sun.COM 	if (cfg.bits.qst == 0)
77*7959SMichael.Speer@Sun.COM 		return (HPI_FAILURE);
78*7959SMichael.Speer@Sun.COM 
79*7959SMichael.Speer@Sun.COM 	return (HPI_SUCCESS);
80*7959SMichael.Speer@Sun.COM }
816349Sqs148142 
826349Sqs148142 /* RX DMA functions */
836349Sqs148142 static hpi_status_t
hpi_rxdma_cfg_rdc_ctl(hpi_handle_t handle,uint8_t rdc,uint8_t op)846349Sqs148142 hpi_rxdma_cfg_rdc_ctl(hpi_handle_t handle, uint8_t rdc, uint8_t op)
856349Sqs148142 {
866349Sqs148142 	rdc_rx_cfg1_t cfg;
876349Sqs148142 	uint32_t count = RXDMA_RESET_TRY_COUNT;
886349Sqs148142 	uint32_t delay_time = RXDMA_RESET_DELAY;
896349Sqs148142 	uint32_t error = HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RESET_ERR, rdc);
906349Sqs148142 
916349Sqs148142 	if (!RXDMA_CHANNEL_VALID(rdc)) {
926349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
936349Sqs148142 		    "hpi_rxdma_cfg_rdc_ctl Illegal RDC number %d \n", rdc));
946349Sqs148142 		return (HPI_RXDMA_RDC_INVALID);
956349Sqs148142 	}
966349Sqs148142 
976349Sqs148142 	switch (op) {
986349Sqs148142 	case RXDMA_OP_ENABLE:
996349Sqs148142 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1006349Sqs148142 		cfg.bits.enable = 1;
1016349Sqs148142 		RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value);
1026349Sqs148142 
1036349Sqs148142 		HXGE_DELAY(delay_time);
104*7959SMichael.Speer@Sun.COM 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1056349Sqs148142 
106*7959SMichael.Speer@Sun.COM 		while ((count--) && (cfg.bits.qst == 1)) {
107*7959SMichael.Speer@Sun.COM 			HXGE_DELAY(delay_time);
108*7959SMichael.Speer@Sun.COM 			RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
109*7959SMichael.Speer@Sun.COM 		}
110*7959SMichael.Speer@Sun.COM 		if (cfg.bits.qst == 1) {
111*7959SMichael.Speer@Sun.COM 			return (HPI_FAILURE);
112*7959SMichael.Speer@Sun.COM 		}
1136349Sqs148142 		break;
114*7959SMichael.Speer@Sun.COM 
1156349Sqs148142 	case RXDMA_OP_DISABLE:
1166349Sqs148142 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1176349Sqs148142 		cfg.bits.enable = 0;
1186349Sqs148142 		RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value);
1196349Sqs148142 
1206349Sqs148142 		HXGE_DELAY(delay_time);
121*7959SMichael.Speer@Sun.COM 		if (hpi_rxdma_cfg_rdc_wait_for_qst(handle,
122*7959SMichael.Speer@Sun.COM 		    rdc) != HPI_SUCCESS) {
1236349Sqs148142 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1246349Sqs148142 			    " hpi_rxdma_cfg_rdc_ctl"
1256349Sqs148142 			    " RXDMA_OP_DISABLE Failed for RDC %d \n",
1266349Sqs148142 			    rdc));
1276349Sqs148142 			return (error);
1286349Sqs148142 		}
129*7959SMichael.Speer@Sun.COM 		break;
1306349Sqs148142 
1316349Sqs148142 	case RXDMA_OP_RESET:
1326349Sqs148142 		cfg.value = 0;
1336349Sqs148142 		cfg.bits.reset = 1;
1346349Sqs148142 		RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value);
1356349Sqs148142 		HXGE_DELAY(delay_time);
1366349Sqs148142 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1376349Sqs148142 
1386349Sqs148142 		while ((count--) && (cfg.bits.qst == 0)) {
1396349Sqs148142 			HXGE_DELAY(delay_time);
1406349Sqs148142 			RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
1416349Sqs148142 		}
1426349Sqs148142 		if (count == 0) {
1436349Sqs148142 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1446349Sqs148142 			    " hpi_rxdma_cfg_rdc_ctl"
1456349Sqs148142 			    " Reset Failed for RDC %d \n", rdc));
1466349Sqs148142 			return (error);
1476349Sqs148142 		}
148*7959SMichael.Speer@Sun.COM 		break;
1496349Sqs148142 
1506349Sqs148142 	default:
1516349Sqs148142 		return (HPI_RXDMA_SW_PARAM_ERROR);
1526349Sqs148142 	}
1536349Sqs148142 
1546349Sqs148142 	return (HPI_SUCCESS);
1556349Sqs148142 }
1566349Sqs148142 
1576349Sqs148142 hpi_status_t
hpi_rxdma_cfg_rdc_enable(hpi_handle_t handle,uint8_t rdc)1586349Sqs148142 hpi_rxdma_cfg_rdc_enable(hpi_handle_t handle, uint8_t rdc)
1596349Sqs148142 {
1606349Sqs148142 	return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_ENABLE));
1616349Sqs148142 }
1626349Sqs148142 
1636349Sqs148142 hpi_status_t
hpi_rxdma_cfg_rdc_disable(hpi_handle_t handle,uint8_t rdc)1646349Sqs148142 hpi_rxdma_cfg_rdc_disable(hpi_handle_t handle, uint8_t rdc)
1656349Sqs148142 {
1666349Sqs148142 	return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_DISABLE));
1676349Sqs148142 }
1686349Sqs148142 
1696349Sqs148142 hpi_status_t
hpi_rxdma_cfg_rdc_reset(hpi_handle_t handle,uint8_t rdc)1706349Sqs148142 hpi_rxdma_cfg_rdc_reset(hpi_handle_t handle, uint8_t rdc)
1716349Sqs148142 {
1726349Sqs148142 	return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_RESET));
1736349Sqs148142 }
1746349Sqs148142 
1756349Sqs148142 static hpi_status_t
hpi_rxdma_cfg_rdc_rcr_ctl(hpi_handle_t handle,uint8_t rdc,uint8_t op,uint16_t param)1766349Sqs148142 hpi_rxdma_cfg_rdc_rcr_ctl(hpi_handle_t handle, uint8_t rdc,
1776349Sqs148142     uint8_t op, uint16_t param)
1786349Sqs148142 {
1796349Sqs148142 	rdc_rcr_cfg_b_t rcr_cfgb;
1806349Sqs148142 
1816349Sqs148142 	if (!RXDMA_CHANNEL_VALID(rdc)) {
1826349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1836349Sqs148142 		    "rxdma_cfg_rdc_rcr_ctl Illegal RDC number %d \n", rdc));
1846349Sqs148142 		return (HPI_RXDMA_RDC_INVALID);
1856349Sqs148142 	}
1866349Sqs148142 
1876349Sqs148142 	RXDMA_REG_READ64(handle, RDC_RCR_CFG_B, rdc, &rcr_cfgb.value);
1886349Sqs148142 
1896349Sqs148142 	switch (op) {
1906349Sqs148142 	case RCR_TIMEOUT_ENABLE:
1916349Sqs148142 		rcr_cfgb.bits.timeout = (uint8_t)param;
1926349Sqs148142 		rcr_cfgb.bits.entout = 1;
1936349Sqs148142 		break;
1946349Sqs148142 
1956349Sqs148142 	case RCR_THRESHOLD:
1966349Sqs148142 		rcr_cfgb.bits.pthres = param;
1976349Sqs148142 		break;
1986349Sqs148142 
1996349Sqs148142 	case RCR_TIMEOUT_DISABLE:
2006349Sqs148142 		rcr_cfgb.bits.entout = 0;
2016349Sqs148142 		break;
2026349Sqs148142 
2036349Sqs148142 	default:
2046349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2056349Sqs148142 		    "rxdma_cfg_rdc_rcr_ctl Illegal opcode %x \n", op));
2066349Sqs148142 		return (HPI_RXDMA_OPCODE_INVALID(rdc));
2076349Sqs148142 	}
2086349Sqs148142 
2096349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value);
2106349Sqs148142 	return (HPI_SUCCESS);
2116349Sqs148142 }
2126349Sqs148142 
2136349Sqs148142 hpi_status_t
hpi_rxdma_cfg_rdc_rcr_threshold(hpi_handle_t handle,uint8_t rdc,uint16_t rcr_threshold)2146349Sqs148142 hpi_rxdma_cfg_rdc_rcr_threshold(hpi_handle_t handle, uint8_t rdc,
2156349Sqs148142     uint16_t rcr_threshold)
2166349Sqs148142 {
2176349Sqs148142 	return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc,
2186349Sqs148142 	    RCR_THRESHOLD, rcr_threshold));
2196349Sqs148142 }
2206349Sqs148142 
2216349Sqs148142 hpi_status_t
hpi_rxdma_cfg_rdc_rcr_timeout(hpi_handle_t handle,uint8_t rdc,uint8_t rcr_timeout)2226349Sqs148142 hpi_rxdma_cfg_rdc_rcr_timeout(hpi_handle_t handle, uint8_t rdc,
2236349Sqs148142     uint8_t rcr_timeout)
2246349Sqs148142 {
2256349Sqs148142 	return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc,
2266349Sqs148142 	    RCR_TIMEOUT_ENABLE, rcr_timeout));
2276349Sqs148142 }
2286349Sqs148142 
2296349Sqs148142 /*
2306349Sqs148142  * Configure The RDC channel Rcv Buffer Ring
2316349Sqs148142  */
2326349Sqs148142 hpi_status_t
hpi_rxdma_cfg_rdc_ring(hpi_handle_t handle,uint8_t rdc,rdc_desc_cfg_t * rdc_desc_cfg)2336349Sqs148142 hpi_rxdma_cfg_rdc_ring(hpi_handle_t handle, uint8_t rdc,
2346349Sqs148142     rdc_desc_cfg_t *rdc_desc_cfg)
2356349Sqs148142 {
2366349Sqs148142 	rdc_rbr_cfg_a_t		cfga;
2376349Sqs148142 	rdc_rbr_cfg_b_t		cfgb;
2386349Sqs148142 	rdc_rx_cfg1_t		cfg1;
2396349Sqs148142 	rdc_rx_cfg2_t		cfg2;
2406349Sqs148142 	rdc_rcr_cfg_a_t		rcr_cfga;
2416349Sqs148142 	rdc_rcr_cfg_b_t		rcr_cfgb;
2426349Sqs148142 	rdc_page_handle_t	page_handle;
2436349Sqs148142 
2446349Sqs148142 	if (!RXDMA_CHANNEL_VALID(rdc)) {
2456349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2466349Sqs148142 		    "rxdma_cfg_rdc_ring Illegal RDC number %d \n", rdc));
2476349Sqs148142 		return (HPI_RXDMA_RDC_INVALID);
2486349Sqs148142 	}
2496349Sqs148142 
2506349Sqs148142 	cfga.value = 0;
2516349Sqs148142 	cfgb.value = 0;
2526349Sqs148142 	cfg1.value = 0;
2536349Sqs148142 	cfg2.value = 0;
2546349Sqs148142 	page_handle.value = 0;
2556349Sqs148142 
2566349Sqs148142 	if (rdc_desc_cfg->mbox_enable == 1) {
2576349Sqs148142 		cfg1.bits.mbaddr_h = (rdc_desc_cfg->mbox_addr >> 32) & 0xfff;
2586349Sqs148142 		cfg2.bits.mbaddr_l = ((rdc_desc_cfg->mbox_addr &
2596349Sqs148142 		    RXDMA_CFIG2_MBADDR_L_MASK) >> RXDMA_CFIG2_MBADDR_L_SHIFT);
2606349Sqs148142 
2616349Sqs148142 		/*
2626349Sqs148142 		 * Only after all the configurations are set, then
2636349Sqs148142 		 * enable the RDC or else configuration fatal error
2646349Sqs148142 		 * will be returned (especially if the Hypervisor
2656349Sqs148142 		 * set up the logical pages with non-zero values.
2666349Sqs148142 		 * This HPI function only sets up the configuration.
2676349Sqs148142 		 * Call the enable function to enable the RDMC!
2686349Sqs148142 		 */
2696349Sqs148142 	}
2706349Sqs148142 
2716349Sqs148142 	if (rdc_desc_cfg->full_hdr == 1)
2726349Sqs148142 		cfg2.bits.full_hdr = 1;
2736349Sqs148142 
2746349Sqs148142 	if (RXDMA_BUFF_OFFSET_VALID(rdc_desc_cfg->offset)) {
2756349Sqs148142 		cfg2.bits.offset = rdc_desc_cfg->offset;
2766349Sqs148142 	} else {
2776349Sqs148142 		cfg2.bits.offset = SW_OFFSET_NO_OFFSET;
2786349Sqs148142 	}
2796349Sqs148142 
2806349Sqs148142 	/* rbr config */
2816349Sqs148142 	cfga.value = (rdc_desc_cfg->rbr_addr &
2826349Sqs148142 	    (RBR_CFIG_A_STDADDR_MASK | RBR_CFIG_A_STDADDR_BASE_MASK));
2836349Sqs148142 
2846349Sqs148142 	/* The remaining 20 bits in the DMA address form the handle */
2856349Sqs148142 	page_handle.bits.handle = (rdc_desc_cfg->rbr_addr >> 44) && 0xfffff;
2866349Sqs148142 
2876349Sqs148142 	/*
2886349Sqs148142 	 * The RBR ring size must be multiple of 64.
2896349Sqs148142 	 */
2906349Sqs148142 	if ((rdc_desc_cfg->rbr_len < RBR_DEFAULT_MIN_LEN) ||
2916349Sqs148142 	    (rdc_desc_cfg->rbr_len > RBR_DEFAULT_MAX_LEN) ||
2926349Sqs148142 	    (rdc_desc_cfg->rbr_len % 64)) {
2936349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2946349Sqs148142 		    "hpi_rxdma_cfg_rdc_ring Illegal RBR Queue Length %d \n",
2956349Sqs148142 		    rdc_desc_cfg->rbr_len));
2966349Sqs148142 		return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RBRSZIE_INVALID, rdc));
2976349Sqs148142 	}
2986349Sqs148142 
2996349Sqs148142 	/*
3006349Sqs148142 	 * The lower 6 bits are hardcoded to 0 and the higher 10 bits are
3016349Sqs148142 	 * stored in len.
3026349Sqs148142 	 */
3036349Sqs148142 	cfga.bits.len = rdc_desc_cfg->rbr_len >> 6;
3046349Sqs148142 	HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL,
3056349Sqs148142 	    "hpi_rxdma_cfg_rdc_ring CFGA 0x%llx len %d (RBR LEN %d)\n",
3066349Sqs148142 	    cfga.value, cfga.bits.len, rdc_desc_cfg->rbr_len));
3076349Sqs148142 
3086349Sqs148142 	/*
3096349Sqs148142 	 * bksize is 1 bit
3106349Sqs148142 	 * Buffer Block Size. b0 - 4K; b1 - 8K.
3116349Sqs148142 	 */
3126349Sqs148142 	if (rdc_desc_cfg->page_size == SIZE_4KB)
3136349Sqs148142 		cfgb.bits.bksize = RBR_BKSIZE_4K;
3146349Sqs148142 	else if (rdc_desc_cfg->page_size == SIZE_8KB)
3156349Sqs148142 		cfgb.bits.bksize = RBR_BKSIZE_8K;
3166349Sqs148142 	else {
3176349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3186349Sqs148142 		    "rxdma_cfg_rdc_ring blksize: Illegal buffer size %d \n",
3196349Sqs148142 		    rdc_desc_cfg->page_size));
3206349Sqs148142 		return (HPI_RXDMA_BUFSZIE_INVALID);
3216349Sqs148142 	}
3226349Sqs148142 
3236349Sqs148142 	/*
3246349Sqs148142 	 * Size 0 of packet buffer. b00 - 256; b01 - 512; b10 - 1K; b11 - resvd.
3256349Sqs148142 	 */
3266349Sqs148142 	if (rdc_desc_cfg->valid0) {
3276349Sqs148142 		if (rdc_desc_cfg->size0 == SIZE_256B)
3286349Sqs148142 			cfgb.bits.bufsz0 = RBR_BUFSZ0_256B;
3296349Sqs148142 		else if (rdc_desc_cfg->size0 == SIZE_512B)
3306349Sqs148142 			cfgb.bits.bufsz0 = RBR_BUFSZ0_512B;
3316349Sqs148142 		else if (rdc_desc_cfg->size0 == SIZE_1KB)
3326349Sqs148142 			cfgb.bits.bufsz0 = RBR_BUFSZ0_1K;
3336349Sqs148142 		else {
3346349Sqs148142 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3356349Sqs148142 			    " rxdma_cfg_rdc_ring"
3366349Sqs148142 			    " blksize0: Illegal buffer size %x \n",
3376349Sqs148142 			    rdc_desc_cfg->size0));
3386349Sqs148142 			return (HPI_RXDMA_BUFSZIE_INVALID);
3396349Sqs148142 		}
3406349Sqs148142 		cfgb.bits.vld0 = 1;
3416349Sqs148142 	} else {
3426349Sqs148142 		cfgb.bits.vld0 = 0;
3436349Sqs148142 	}
3446349Sqs148142 
3456349Sqs148142 	/*
3466349Sqs148142 	 * Size 1 of packet buffer. b0 - 1K; b1 - 2K.
3476349Sqs148142 	 */
3486349Sqs148142 	if (rdc_desc_cfg->valid1) {
3496349Sqs148142 		if (rdc_desc_cfg->size1 == SIZE_1KB)
3506349Sqs148142 			cfgb.bits.bufsz1 = RBR_BUFSZ1_1K;
3516349Sqs148142 		else if (rdc_desc_cfg->size1 == SIZE_2KB)
3526349Sqs148142 			cfgb.bits.bufsz1 = RBR_BUFSZ1_2K;
3536349Sqs148142 		else {
3546349Sqs148142 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3556349Sqs148142 			    " rxdma_cfg_rdc_ring"
3566349Sqs148142 			    " blksize1: Illegal buffer size %x \n",
3576349Sqs148142 			    rdc_desc_cfg->size1));
3586349Sqs148142 			return (HPI_RXDMA_BUFSZIE_INVALID);
3596349Sqs148142 		}
3606349Sqs148142 		cfgb.bits.vld1 = 1;
3616349Sqs148142 	} else {
3626349Sqs148142 		cfgb.bits.vld1 = 0;
3636349Sqs148142 	}
3646349Sqs148142 
3656349Sqs148142 	/*
3666349Sqs148142 	 * Size 2 of packet buffer. b0 - 2K; b1 - 4K.
3676349Sqs148142 	 */
3686349Sqs148142 	if (rdc_desc_cfg->valid2) {
3696349Sqs148142 		if (rdc_desc_cfg->size2 == SIZE_2KB)
3706349Sqs148142 			cfgb.bits.bufsz2 = RBR_BUFSZ2_2K;
3716349Sqs148142 		else if (rdc_desc_cfg->size2 == SIZE_4KB)
3726349Sqs148142 			cfgb.bits.bufsz2 = RBR_BUFSZ2_4K;
3736349Sqs148142 		else {
3746349Sqs148142 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3756349Sqs148142 			    " rxdma_cfg_rdc_ring"
3766349Sqs148142 			    " blksize2: Illegal buffer size %x \n",
3776349Sqs148142 			    rdc_desc_cfg->size2));
3786349Sqs148142 			return (HPI_RXDMA_BUFSZIE_INVALID);
3796349Sqs148142 		}
3806349Sqs148142 		cfgb.bits.vld2 = 1;
3816349Sqs148142 	} else {
3826349Sqs148142 		cfgb.bits.vld2 = 0;
3836349Sqs148142 	}
3846349Sqs148142 
3856349Sqs148142 	rcr_cfga.value = (rdc_desc_cfg->rcr_addr &
3866349Sqs148142 	    (RCRCFIG_A_STADDR_MASK | RCRCFIG_A_STADDR_BASE_MASK));
3876349Sqs148142 
3886349Sqs148142 	/*
3896349Sqs148142 	 * The rcr len must be multiple of 32.
3906349Sqs148142 	 */
3916349Sqs148142 	if ((rdc_desc_cfg->rcr_len < RCR_DEFAULT_MIN_LEN) ||
3926349Sqs148142 	    (rdc_desc_cfg->rcr_len > HXGE_RCR_MAX) ||
3936349Sqs148142 	    (rdc_desc_cfg->rcr_len % 32)) {
3946349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3956349Sqs148142 		    " rxdma_cfg_rdc_ring Illegal RCR Queue Length %d \n",
3966349Sqs148142 		    rdc_desc_cfg->rcr_len));
3976349Sqs148142 		return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RCRSZIE_INVALID, rdc));
3986349Sqs148142 	}
3996349Sqs148142 
4006349Sqs148142 	/*
4016349Sqs148142 	 * Bits 15:5 of the maximum number of 8B entries in RCR.  Bits 4:0 are
4026349Sqs148142 	 * hard-coded to zero.  The maximum size is 2^16 - 32.
4036349Sqs148142 	 */
4046349Sqs148142 	rcr_cfga.bits.len = rdc_desc_cfg->rcr_len >> 5;
4056349Sqs148142 
4066349Sqs148142 	rcr_cfgb.value = 0;
4076349Sqs148142 	if (rdc_desc_cfg->rcr_timeout_enable == 1) {
4086349Sqs148142 		/* check if the rcr timeout value is valid */
4096349Sqs148142 
4106349Sqs148142 		if (RXDMA_RCR_TO_VALID(rdc_desc_cfg->rcr_timeout)) {
4116349Sqs148142 			rcr_cfgb.bits.timeout = rdc_desc_cfg->rcr_timeout;
4126349Sqs148142 			rcr_cfgb.bits.entout = 1;
4136349Sqs148142 		} else {
4146349Sqs148142 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
4156349Sqs148142 			    " rxdma_cfg_rdc_ring"
4166349Sqs148142 			    " Illegal RCR Timeout value %d \n",
4176349Sqs148142 			    rdc_desc_cfg->rcr_timeout));
4186349Sqs148142 			rcr_cfgb.bits.entout = 0;
4196349Sqs148142 		}
4206349Sqs148142 	} else {
4216349Sqs148142 		rcr_cfgb.bits.entout = 0;
4226349Sqs148142 	}
4236349Sqs148142 
4246349Sqs148142 	/* check if the rcr threshold value is valid */
4256349Sqs148142 	if (RXDMA_RCR_THRESH_VALID(rdc_desc_cfg->rcr_threshold)) {
4266349Sqs148142 		rcr_cfgb.bits.pthres = rdc_desc_cfg->rcr_threshold;
4276349Sqs148142 	} else {
4286349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
4296349Sqs148142 		    " rxdma_cfg_rdc_ring Illegal RCR Threshold value %d \n",
4306349Sqs148142 		    rdc_desc_cfg->rcr_threshold));
4316349Sqs148142 		rcr_cfgb.bits.pthres = 1;
4326349Sqs148142 	}
4336349Sqs148142 
4346349Sqs148142 	/* now do the actual HW configuration */
4356349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg1.value);
4366349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_RX_CFG2, rdc, cfg2.value);
4376349Sqs148142 
4386349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_A, rdc, cfga.value);
4396349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_B, rdc, cfgb.value);
4406349Sqs148142 
4416349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_A, rdc, rcr_cfga.value);
4426349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value);
4436349Sqs148142 
4446349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_handle.value);
4456349Sqs148142 
4466349Sqs148142 	return (HPI_SUCCESS);
4476349Sqs148142 }
4486349Sqs148142 
4496349Sqs148142 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)4506349Sqs148142 hpi_rxdma_ring_perr_stat_get(hpi_handle_t handle,
4516349Sqs148142     rdc_pref_par_log_t *pre_log, rdc_pref_par_log_t *sha_log)
4526349Sqs148142 {
4536349Sqs148142 	/*
4546349Sqs148142 	 * Hydra doesn't have details about these errors.
4556349Sqs148142 	 * It only provides the addresses of the errors.
4566349Sqs148142 	 */
4576349Sqs148142 	HXGE_REG_RD64(handle, RDC_PREF_PAR_LOG, &pre_log->value);
4586349Sqs148142 	HXGE_REG_RD64(handle, RDC_SHADOW_PAR_LOG, &sha_log->value);
4596349Sqs148142 
4606349Sqs148142 	return (HPI_SUCCESS);
4616349Sqs148142 }
4626349Sqs148142 
4636349Sqs148142 
4646349Sqs148142 /* system wide conf functions */
4656349Sqs148142 
4666349Sqs148142 hpi_status_t
hpi_rxdma_cfg_clock_div_set(hpi_handle_t handle,uint16_t count)4676349Sqs148142 hpi_rxdma_cfg_clock_div_set(hpi_handle_t handle, uint16_t count)
4686349Sqs148142 {
4696349Sqs148142 	uint64_t	offset;
4706349Sqs148142 	rdc_clock_div_t	clk_div;
4716349Sqs148142 
4726349Sqs148142 	offset = RDC_CLOCK_DIV;
4736349Sqs148142 
4746349Sqs148142 	clk_div.value = 0;
4756349Sqs148142 	clk_div.bits.count = count;
4766349Sqs148142 	HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL,
4776349Sqs148142 	    " hpi_rxdma_cfg_clock_div_set: add 0x%llx "
4786349Sqs148142 	    "handle 0x%llx value 0x%llx",
4796349Sqs148142 	    handle.regp, handle.regh, clk_div.value));
4806349Sqs148142 
4816349Sqs148142 	HXGE_REG_WR64(handle, offset, clk_div.value);
4826349Sqs148142 
4836349Sqs148142 	return (HPI_SUCCESS);
4846349Sqs148142 }
4856349Sqs148142 
4866349Sqs148142 
4876349Sqs148142 hpi_status_t
hpi_rxdma_rdc_rbr_stat_get(hpi_handle_t handle,uint8_t rdc,rdc_rbr_qlen_t * rbr_stat)4886349Sqs148142 hpi_rxdma_rdc_rbr_stat_get(hpi_handle_t handle, uint8_t rdc,
4896349Sqs148142     rdc_rbr_qlen_t *rbr_stat)
4906349Sqs148142 {
4916349Sqs148142 	if (!RXDMA_CHANNEL_VALID(rdc)) {
4926349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
4936349Sqs148142 		    " rxdma_rdc_rbr_stat_get Illegal RDC Number %d \n", rdc));
4946349Sqs148142 		return (HPI_RXDMA_RDC_INVALID);
4956349Sqs148142 	}
4966349Sqs148142 
4976349Sqs148142 	RXDMA_REG_READ64(handle, RDC_RBR_QLEN, rdc, &rbr_stat->value);
4986349Sqs148142 	return (HPI_SUCCESS);
4996349Sqs148142 }
5006349Sqs148142 
5016349Sqs148142 
5026349Sqs148142 hpi_status_t
hpi_rxdma_rdc_rcr_qlen_get(hpi_handle_t handle,uint8_t rdc,uint16_t * rcr_qlen)5036349Sqs148142 hpi_rxdma_rdc_rcr_qlen_get(hpi_handle_t handle, uint8_t rdc,
5046349Sqs148142     uint16_t *rcr_qlen)
5056349Sqs148142 {
5066349Sqs148142 	rdc_rcr_qlen_t stats;
5076349Sqs148142 
5086349Sqs148142 	if (!RXDMA_CHANNEL_VALID(rdc)) {
5096349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5106349Sqs148142 		    " rxdma_rdc_rcr_qlen_get Illegal RDC Number %d \n", rdc));
5116349Sqs148142 		return (HPI_RXDMA_RDC_INVALID);
5126349Sqs148142 	}
5136349Sqs148142 
5146349Sqs148142 	RXDMA_REG_READ64(handle, RDC_RCR_QLEN, rdc, &stats.value);
5156349Sqs148142 	*rcr_qlen =  stats.bits.qlen;
5166349Sqs148142 	HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL,
5176349Sqs148142 	    " rxdma_rdc_rcr_qlen_get RDC %d qlen %x qlen %x\n",
5186349Sqs148142 	    rdc, *rcr_qlen, stats.bits.qlen));
5196349Sqs148142 	return (HPI_SUCCESS);
5206349Sqs148142 }
5216349Sqs148142 
5226349Sqs148142 hpi_status_t
hpi_rxdma_channel_rbr_empty_clear(hpi_handle_t handle,uint8_t channel)5236349Sqs148142 hpi_rxdma_channel_rbr_empty_clear(hpi_handle_t handle, uint8_t channel)
5246349Sqs148142 {
5256349Sqs148142 	rdc_stat_t	cs;
5266349Sqs148142 
5276349Sqs148142 	if (!RXDMA_CHANNEL_VALID(channel)) {
5286349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5296349Sqs148142 		    " hpi_rxdma_channel_rbr_empty_clear", " channel", channel));
5306349Sqs148142 		return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel));
5316349Sqs148142 	}
5326349Sqs148142 
5336349Sqs148142 	RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value);
5346349Sqs148142 	cs.bits.rbr_empty = 1;
5356349Sqs148142 	RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value);
5366349Sqs148142 
5376349Sqs148142 	return (HPI_SUCCESS);
5386349Sqs148142 }
5396349Sqs148142 
5406349Sqs148142 /*
5416349Sqs148142  * This function is called to operate on the control and status register.
5426349Sqs148142  */
5436349Sqs148142 hpi_status_t
hpi_rxdma_control_status(hpi_handle_t handle,io_op_t op_mode,uint8_t channel,rdc_stat_t * cs_p)5446349Sqs148142 hpi_rxdma_control_status(hpi_handle_t handle, io_op_t op_mode, uint8_t channel,
5456349Sqs148142     rdc_stat_t *cs_p)
5466349Sqs148142 {
5476349Sqs148142 	int		status = HPI_SUCCESS;
5486349Sqs148142 	rdc_stat_t	cs;
5496349Sqs148142 
5506349Sqs148142 	if (!RXDMA_CHANNEL_VALID(channel)) {
5516349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5526349Sqs148142 		    "hpi_rxdma_control_status", "channel", channel));
5536349Sqs148142 		return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel));
5546349Sqs148142 	}
5556349Sqs148142 
5566349Sqs148142 	switch (op_mode) {
5576349Sqs148142 	case OP_GET:
5586349Sqs148142 		RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs_p->value);
5596349Sqs148142 		break;
5606349Sqs148142 
5616349Sqs148142 	case OP_SET:
5626349Sqs148142 		RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs_p->value);
5636349Sqs148142 		break;
5646349Sqs148142 
5656349Sqs148142 	case OP_UPDATE:
5666349Sqs148142 		RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value);
5676349Sqs148142 		RXDMA_REG_WRITE64(handle, RDC_STAT, channel,
5686349Sqs148142 		    cs_p->value | cs.value);
5696349Sqs148142 		break;
5706349Sqs148142 
5716349Sqs148142 	default:
5726349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5736349Sqs148142 		    "hpi_rxdma_control_status", "control", op_mode));
5746349Sqs148142 		return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel));
5756349Sqs148142 	}
5766349Sqs148142 
5776349Sqs148142 	return (status);
5786349Sqs148142 }
5796349Sqs148142 
5806349Sqs148142 /*
5816349Sqs148142  * This function is called to operate on the event mask
5826349Sqs148142  * register which is used for generating interrupts.
5836349Sqs148142  */
5846349Sqs148142 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)5856349Sqs148142 hpi_rxdma_event_mask(hpi_handle_t handle, io_op_t op_mode, uint8_t channel,
5866349Sqs148142     rdc_int_mask_t *mask_p)
5876349Sqs148142 {
5886349Sqs148142 	int		status = HPI_SUCCESS;
5896349Sqs148142 	rdc_int_mask_t	mask;
5906349Sqs148142 
5916349Sqs148142 	if (!RXDMA_CHANNEL_VALID(channel)) {
5926349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
5936349Sqs148142 		    "hpi_rxdma_event_mask", "channel", channel));
5946349Sqs148142 		return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel));
5956349Sqs148142 	}
5966349Sqs148142 
5976349Sqs148142 	switch (op_mode) {
5986349Sqs148142 	case OP_GET:
5996349Sqs148142 		RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask_p->value);
6006349Sqs148142 		break;
6016349Sqs148142 
6026349Sqs148142 	case OP_SET:
6036349Sqs148142 		RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel, mask_p->value);
6046349Sqs148142 		break;
6056349Sqs148142 
6066349Sqs148142 	case OP_UPDATE:
6076349Sqs148142 		RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask.value);
6086349Sqs148142 		RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel,
6096349Sqs148142 		    mask_p->value | mask.value);
6106349Sqs148142 		break;
6116349Sqs148142 
6126349Sqs148142 	default:
6136349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
6146349Sqs148142 		    "hpi_rxdma_event_mask", "eventmask", op_mode));
6156349Sqs148142 		return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel));
6166349Sqs148142 	}
6176349Sqs148142 
6186349Sqs148142 	return (status);
6196349Sqs148142 }
620