xref: /onnv-gate/usr/src/uts/common/io/hxge/hpi_txdma.c (revision 6864:50c1b31ccb24)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
276349Sqs148142 
286349Sqs148142 #include <hpi_txdma.h>
29*6864Sqs148142 #include <hxge_impl.h>
306349Sqs148142 
316349Sqs148142 #define	TXDMA_WAIT_LOOP		10000
326349Sqs148142 #define	TXDMA_WAIT_MSEC		5
336349Sqs148142 
346349Sqs148142 static hpi_status_t hpi_txdma_control_reset_wait(hpi_handle_t handle,
356349Sqs148142     uint8_t channel);
366349Sqs148142 
376349Sqs148142 hpi_status_t
hpi_txdma_log_page_handle_set(hpi_handle_t handle,uint8_t channel,tdc_page_handle_t * hdl_p)386349Sqs148142 hpi_txdma_log_page_handle_set(hpi_handle_t handle, uint8_t channel,
396349Sqs148142     tdc_page_handle_t *hdl_p)
406349Sqs148142 {
416349Sqs148142 	int status = HPI_SUCCESS;
426349Sqs148142 
436349Sqs148142 	if (!TXDMA_CHANNEL_VALID(channel)) {
446349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
456349Sqs148142 		    " hpi_txdma_log_page_handle_set"
466349Sqs148142 		    " Invalid Input: channel <0x%x>", channel));
476349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel));
486349Sqs148142 	}
496349Sqs148142 
506349Sqs148142 	TXDMA_REG_WRITE64(handle, TDC_PAGE_HANDLE, channel, hdl_p->value);
516349Sqs148142 
526349Sqs148142 	return (status);
536349Sqs148142 }
546349Sqs148142 
556349Sqs148142 hpi_status_t
hpi_txdma_channel_reset(hpi_handle_t handle,uint8_t channel)566349Sqs148142 hpi_txdma_channel_reset(hpi_handle_t handle, uint8_t channel)
576349Sqs148142 {
586349Sqs148142 	HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL,
596349Sqs148142 	    " hpi_txdma_channel_reset" " RESETTING", channel));
606349Sqs148142 	return (hpi_txdma_channel_control(handle, TXDMA_RESET, channel));
616349Sqs148142 }
626349Sqs148142 
636349Sqs148142 hpi_status_t
hpi_txdma_channel_init_enable(hpi_handle_t handle,uint8_t channel)646349Sqs148142 hpi_txdma_channel_init_enable(hpi_handle_t handle, uint8_t channel)
656349Sqs148142 {
666349Sqs148142 	return (hpi_txdma_channel_control(handle, TXDMA_INIT_START, channel));
676349Sqs148142 }
686349Sqs148142 
696349Sqs148142 hpi_status_t
hpi_txdma_channel_enable(hpi_handle_t handle,uint8_t channel)706349Sqs148142 hpi_txdma_channel_enable(hpi_handle_t handle, uint8_t channel)
716349Sqs148142 {
726349Sqs148142 	return (hpi_txdma_channel_control(handle, TXDMA_START, channel));
736349Sqs148142 }
746349Sqs148142 
756349Sqs148142 hpi_status_t
hpi_txdma_channel_disable(hpi_handle_t handle,uint8_t channel)766349Sqs148142 hpi_txdma_channel_disable(hpi_handle_t handle, uint8_t channel)
776349Sqs148142 {
786349Sqs148142 	return (hpi_txdma_channel_control(handle, TXDMA_STOP, channel));
796349Sqs148142 }
806349Sqs148142 
816349Sqs148142 hpi_status_t
hpi_txdma_channel_mbox_enable(hpi_handle_t handle,uint8_t channel)826349Sqs148142 hpi_txdma_channel_mbox_enable(hpi_handle_t handle, uint8_t channel)
836349Sqs148142 {
846349Sqs148142 	return (hpi_txdma_channel_control(handle, TXDMA_MBOX_ENABLE, channel));
856349Sqs148142 }
866349Sqs148142 
876349Sqs148142 hpi_status_t
hpi_txdma_channel_control(hpi_handle_t handle,txdma_cs_cntl_t control,uint8_t channel)886349Sqs148142 hpi_txdma_channel_control(hpi_handle_t handle, txdma_cs_cntl_t control,
896349Sqs148142     uint8_t channel)
906349Sqs148142 {
916349Sqs148142 	int		status = HPI_SUCCESS;
926349Sqs148142 	tdc_stat_t	cs;
936349Sqs148142 	tdc_tdr_cfg_t	cfg;
946349Sqs148142 
956349Sqs148142 	if (!TXDMA_CHANNEL_VALID(channel)) {
966349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
976349Sqs148142 		    " hpi_txdma_channel_control"
986349Sqs148142 		    " Invalid Input: channel <0x%x>", channel));
996349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel));
1006349Sqs148142 	}
1016349Sqs148142 
1026349Sqs148142 	switch (control) {
1036349Sqs148142 	case TXDMA_INIT_RESET:
1046349Sqs148142 		cfg.value = 0;
1056349Sqs148142 		TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &cfg.value);
1066349Sqs148142 		cfg.bits.reset = 1;
1076349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value);
1086349Sqs148142 		return (hpi_txdma_control_reset_wait(handle, channel));
1096349Sqs148142 
1106349Sqs148142 	case TXDMA_INIT_START:
1116349Sqs148142 		cfg.value = 0;
1126349Sqs148142 		TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &cfg.value);
1136349Sqs148142 		cfg.bits.enable = 1;
1146349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value);
1156349Sqs148142 		break;
1166349Sqs148142 
1176349Sqs148142 	case TXDMA_RESET:
1186349Sqs148142 		/*
1196349Sqs148142 		 * Sets reset bit only (Hardware will reset all the RW bits but
1206349Sqs148142 		 * leave the RO bits alone.
1216349Sqs148142 		 */
1226349Sqs148142 		cfg.value = 0;
1236349Sqs148142 		cfg.bits.reset = 1;
1246349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value);
1256349Sqs148142 		return (hpi_txdma_control_reset_wait(handle, channel));
1266349Sqs148142 
1276349Sqs148142 	case TXDMA_START:
1286349Sqs148142 		/* Enable the DMA channel */
1296349Sqs148142 		TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &cfg.value);
1306349Sqs148142 		cfg.bits.enable = 1;
1316349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value);
1326349Sqs148142 		break;
1336349Sqs148142 
1346349Sqs148142 	case TXDMA_STOP:
1356349Sqs148142 		/* Disable the DMA channel */
1366349Sqs148142 		TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &cfg.value);
1376349Sqs148142 		cfg.bits.enable = 0;
1386349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value);
1396349Sqs148142 		status = hpi_txdma_control_stop_wait(handle, channel);
1406349Sqs148142 		if (status) {
1416349Sqs148142 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1426349Sqs148142 			    "Cannot stop channel %d (TXC hung!)", channel));
1436349Sqs148142 		}
1446349Sqs148142 		break;
1456349Sqs148142 
1466349Sqs148142 	case TXDMA_MBOX_ENABLE:
1476349Sqs148142 		/*
1486349Sqs148142 		 * Write 1 to MB bit to enable mailbox update (cleared to 0 by
1496349Sqs148142 		 * hardware after update).
1506349Sqs148142 		 */
1516349Sqs148142 		TXDMA_REG_READ64(handle, TDC_STAT, channel, &cs.value);
1526349Sqs148142 		cs.bits.mb = 1;
1536349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_STAT, channel, cs.value);
1546349Sqs148142 		break;
1556349Sqs148142 
1566349Sqs148142 	default:
1576349Sqs148142 		status = (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel));
1586349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1596349Sqs148142 		    " hpi_txdma_channel_control"
1606349Sqs148142 		    " Invalid Input: control <0x%x>", control));
1616349Sqs148142 	}
1626349Sqs148142 
1636349Sqs148142 	return (status);
1646349Sqs148142 }
1656349Sqs148142 
1666349Sqs148142 hpi_status_t
hpi_txdma_control_status(hpi_handle_t handle,io_op_t op_mode,uint8_t channel,tdc_stat_t * cs_p)1676349Sqs148142 hpi_txdma_control_status(hpi_handle_t handle, io_op_t op_mode, uint8_t channel,
1686349Sqs148142     tdc_stat_t *cs_p)
1696349Sqs148142 {
1706349Sqs148142 	int		status = HPI_SUCCESS;
1716349Sqs148142 	tdc_stat_t	txcs;
1726349Sqs148142 
1736349Sqs148142 	if (!TXDMA_CHANNEL_VALID(channel)) {
1746349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1756349Sqs148142 		    " hpi_txdma_control_status"
1766349Sqs148142 		    " Invalid Input: channel <0x%x>", channel));
1776349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel));
1786349Sqs148142 	}
1796349Sqs148142 	switch (op_mode) {
1806349Sqs148142 	case OP_GET:
1816349Sqs148142 		TXDMA_REG_READ64(handle, TDC_STAT, channel, &cs_p->value);
1826349Sqs148142 		break;
1836349Sqs148142 
1846349Sqs148142 	case OP_SET:
1856349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_STAT, channel, cs_p->value);
1866349Sqs148142 		break;
1876349Sqs148142 
1886349Sqs148142 	case OP_UPDATE:
1896349Sqs148142 		TXDMA_REG_READ64(handle, TDC_STAT, channel, &txcs.value);
1906349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_STAT, channel,
1916349Sqs148142 		    cs_p->value | txcs.value);
1926349Sqs148142 		break;
1936349Sqs148142 
1946349Sqs148142 	default:
1956349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
1966349Sqs148142 		    " hpi_txdma_control_status"
1976349Sqs148142 		    " Invalid Input: control <0x%x>", op_mode));
1986349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel));
1996349Sqs148142 	}
2006349Sqs148142 
2016349Sqs148142 	return (status);
2026349Sqs148142 }
2036349Sqs148142 
2046349Sqs148142 hpi_status_t
hpi_txdma_event_mask(hpi_handle_t handle,io_op_t op_mode,uint8_t channel,tdc_int_mask_t * mask_p)2056349Sqs148142 hpi_txdma_event_mask(hpi_handle_t handle, io_op_t op_mode, uint8_t channel,
2066349Sqs148142     tdc_int_mask_t *mask_p)
2076349Sqs148142 {
2086349Sqs148142 	int		status = HPI_SUCCESS;
2096349Sqs148142 	tdc_int_mask_t	mask;
2106349Sqs148142 
2116349Sqs148142 	if (!TXDMA_CHANNEL_VALID(channel)) {
2126349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2136349Sqs148142 		    " hpi_txdma_event_mask Invalid Input: channel <0x%x>",
2146349Sqs148142 		    channel));
2156349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel));
2166349Sqs148142 	}
2176349Sqs148142 	switch (op_mode) {
2186349Sqs148142 	case OP_GET:
2196349Sqs148142 		TXDMA_REG_READ64(handle, TDC_INT_MASK, channel, &mask_p->value);
2206349Sqs148142 		break;
2216349Sqs148142 
2226349Sqs148142 	case OP_SET:
2236349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_INT_MASK, channel, mask_p->value);
2246349Sqs148142 		break;
2256349Sqs148142 
2266349Sqs148142 	case OP_UPDATE:
2276349Sqs148142 		TXDMA_REG_READ64(handle, TDC_INT_MASK, channel, &mask.value);
2286349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_INT_MASK, channel,
2296349Sqs148142 		    mask_p->value | mask.value);
2306349Sqs148142 		break;
2316349Sqs148142 
2326349Sqs148142 	default:
2336349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2346349Sqs148142 		    " hpi_txdma_event_mask Invalid Input: eventmask <0x%x>",
2356349Sqs148142 		    op_mode));
2366349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel));
2376349Sqs148142 	}
2386349Sqs148142 
2396349Sqs148142 	return (status);
2406349Sqs148142 }
2416349Sqs148142 
2426349Sqs148142 hpi_status_t
hpi_txdma_ring_config(hpi_handle_t handle,io_op_t op_mode,uint8_t channel,uint64_t * reg_data)2436349Sqs148142 hpi_txdma_ring_config(hpi_handle_t handle, io_op_t op_mode,
2446349Sqs148142     uint8_t channel, uint64_t *reg_data)
2456349Sqs148142 {
2466349Sqs148142 	int status = HPI_SUCCESS;
2476349Sqs148142 
2486349Sqs148142 	if (!TXDMA_CHANNEL_VALID(channel)) {
2496349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2506349Sqs148142 		    " hpi_txdma_ring_config"
2516349Sqs148142 		    " Invalid Input: channel <0x%x>", channel));
2526349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel));
2536349Sqs148142 	}
2546349Sqs148142 	switch (op_mode) {
2556349Sqs148142 	case OP_GET:
2566349Sqs148142 		TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, reg_data);
2576349Sqs148142 		break;
2586349Sqs148142 
2596349Sqs148142 	case OP_SET:
2606349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, *reg_data);
2616349Sqs148142 		break;
2626349Sqs148142 
2636349Sqs148142 	default:
2646349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2656349Sqs148142 		    " hpi_txdma_ring_config"
2666349Sqs148142 		    " Invalid Input: ring_config <0x%x>", op_mode));
2676349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel));
2686349Sqs148142 	}
2696349Sqs148142 
2706349Sqs148142 	return (status);
2716349Sqs148142 }
2726349Sqs148142 
2736349Sqs148142 hpi_status_t
hpi_txdma_mbox_config(hpi_handle_t handle,io_op_t op_mode,uint8_t channel,uint64_t * mbox_addr)2746349Sqs148142 hpi_txdma_mbox_config(hpi_handle_t handle, io_op_t op_mode,
2756349Sqs148142     uint8_t channel, uint64_t *mbox_addr)
2766349Sqs148142 {
2776349Sqs148142 	int		status = HPI_SUCCESS;
2786349Sqs148142 	tdc_mbh_t	mh;
2796349Sqs148142 	tdc_mbl_t	ml;
2806349Sqs148142 
2816349Sqs148142 	if (!TXDMA_CHANNEL_VALID(channel)) {
2826349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
2836349Sqs148142 		    " hpi_txdma_mbox_config Invalid Input: channel <0x%x>",
2846349Sqs148142 		    channel));
2856349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel));
2866349Sqs148142 	}
2876349Sqs148142 
2886349Sqs148142 	mh.value = ml.value = 0;
2896349Sqs148142 
2906349Sqs148142 	switch (op_mode) {
2916349Sqs148142 	case OP_GET:
2926349Sqs148142 		TXDMA_REG_READ64(handle, TDC_MBH, channel, &mh.value);
2936349Sqs148142 		TXDMA_REG_READ64(handle, TDC_MBL, channel, &ml.value);
2946349Sqs148142 		*mbox_addr = ml.value;
2956349Sqs148142 		*mbox_addr |= (mh.value << TDC_MBH_ADDR_SHIFT);
2966349Sqs148142 
2976349Sqs148142 		break;
2986349Sqs148142 
2996349Sqs148142 	case OP_SET:
3006349Sqs148142 		ml.bits.mbaddr = ((*mbox_addr & TDC_MBL_MASK) >> TDC_MBL_SHIFT);
3016349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_MBL, channel, ml.value);
3026349Sqs148142 		mh.bits.mbaddr = ((*mbox_addr >> TDC_MBH_ADDR_SHIFT) &
3036349Sqs148142 		    TDC_MBH_MASK);
3046349Sqs148142 		TXDMA_REG_WRITE64(handle, TDC_MBH, channel, mh.value);
3056349Sqs148142 		break;
3066349Sqs148142 
3076349Sqs148142 	default:
3086349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3096349Sqs148142 		    " hpi_txdma_mbox_config Invalid Input: mbox <0x%x>",
3106349Sqs148142 		    op_mode));
3116349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel));
3126349Sqs148142 	}
3136349Sqs148142 
3146349Sqs148142 	return (status);
3156349Sqs148142 }
3166349Sqs148142 
3176349Sqs148142 /*
3186349Sqs148142  * This function is called to set up a transmit descriptor entry.
3196349Sqs148142  */
3206349Sqs148142 hpi_status_t
hpi_txdma_desc_gather_set(hpi_handle_t handle,p_tx_desc_t desc_p,uint8_t gather_index,boolean_t mark,uint8_t ngathers,uint64_t dma_ioaddr,uint32_t transfer_len)3216349Sqs148142 hpi_txdma_desc_gather_set(hpi_handle_t handle, p_tx_desc_t desc_p,
3226349Sqs148142     uint8_t gather_index, boolean_t mark, uint8_t ngathers,
3236349Sqs148142     uint64_t dma_ioaddr, uint32_t transfer_len)
3246349Sqs148142 {
3256349Sqs148142 	int status;
3266349Sqs148142 
3276349Sqs148142 	status = HPI_TXDMA_GATHER_INDEX(gather_index);
3286349Sqs148142 	if (status) {
3296349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3306349Sqs148142 		    " hpi_txdma_desc_gather_set"
3316349Sqs148142 		    " Invalid Input: gather_index <0x%x>", gather_index));
3326349Sqs148142 		return (status);
3336349Sqs148142 	}
3346349Sqs148142 	if (transfer_len > TX_MAX_TRANSFER_LENGTH) {
3356349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3366349Sqs148142 		    " hpi_txdma_desc_gather_set"
3376349Sqs148142 		    " Invalid Input: tr_len <0x%x>", transfer_len));
3386349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_XFER_LEN_INVALID);
3396349Sqs148142 	}
3406349Sqs148142 	if (gather_index == 0) {
3416349Sqs148142 		desc_p->bits.sop = 1;
3426349Sqs148142 		desc_p->bits.mark = mark;
3436349Sqs148142 		desc_p->bits.num_ptr = ngathers;
3446349Sqs148142 		HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL,
3456349Sqs148142 		    "hpi_txdma_gather_set: SOP len %d (%d)",
3466349Sqs148142 		    desc_p->bits.tr_len, transfer_len));
3476349Sqs148142 	}
3486349Sqs148142 	desc_p->bits.tr_len = transfer_len;
349*6864Sqs148142 	desc_p->bits.sad = dma_ioaddr >> 32;
350*6864Sqs148142 	desc_p->bits.sad_l = dma_ioaddr & 0xffffffff;
3516349Sqs148142 
3526349Sqs148142 	HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL,
3536349Sqs148142 	    "hpi_txdma_gather_set: xfer len %d to set (%d)",
3546349Sqs148142 	    desc_p->bits.tr_len, transfer_len));
3556349Sqs148142 
3566349Sqs148142 	HXGE_MEM_PIO_WRITE64(handle, desc_p->value);
3576349Sqs148142 
3586349Sqs148142 	return (status);
3596349Sqs148142 }
3606349Sqs148142 
3616349Sqs148142 hpi_status_t
hpi_txdma_desc_set_zero(hpi_handle_t handle,uint16_t entries)3626349Sqs148142 hpi_txdma_desc_set_zero(hpi_handle_t handle, uint16_t entries)
3636349Sqs148142 {
3646349Sqs148142 	uint32_t	offset;
3656349Sqs148142 	int		i;
3666349Sqs148142 
3676349Sqs148142 	/*
3686349Sqs148142 	 * Assume no wrapped around.
3696349Sqs148142 	 */
3706349Sqs148142 	offset = 0;
3716349Sqs148142 	for (i = 0; i < entries; i++) {
3726349Sqs148142 		HXGE_REG_WR64(handle, offset, 0);
3736349Sqs148142 		offset += (i * (sizeof (tx_desc_t)));
3746349Sqs148142 	}
3756349Sqs148142 
3766349Sqs148142 	return (HPI_SUCCESS);
3776349Sqs148142 }
3786349Sqs148142 
3796349Sqs148142 /*
3806349Sqs148142  * This function is called to get the transmit ring head index.
3816349Sqs148142  */
3826349Sqs148142 hpi_status_t
hpi_txdma_ring_head_get(hpi_handle_t handle,uint8_t channel,tdc_tdr_head_t * hdl_p)3836349Sqs148142 hpi_txdma_ring_head_get(hpi_handle_t handle, uint8_t channel,
3846349Sqs148142     tdc_tdr_head_t *hdl_p)
3856349Sqs148142 {
3866349Sqs148142 	int status = HPI_SUCCESS;
3876349Sqs148142 
3886349Sqs148142 	if (!TXDMA_CHANNEL_VALID(channel)) {
3896349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
3906349Sqs148142 		    " hpi_txdma_ring_head_get"
3916349Sqs148142 		    " Invalid Input: channel <0x%x>", channel));
3926349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel));
3936349Sqs148142 	}
3946349Sqs148142 	TXDMA_REG_READ64(handle, TDC_TDR_HEAD, channel, &hdl_p->value);
3956349Sqs148142 
3966349Sqs148142 	return (status);
3976349Sqs148142 }
3986349Sqs148142 
3996349Sqs148142 /*
4006349Sqs148142  * Dumps the contents of transmit descriptors.
4016349Sqs148142  */
4026349Sqs148142 /*ARGSUSED*/
4036349Sqs148142 void
hpi_txdma_dump_desc_one(hpi_handle_t handle,p_tx_desc_t desc_p,int desc_index)4046349Sqs148142 hpi_txdma_dump_desc_one(hpi_handle_t handle, p_tx_desc_t desc_p, int desc_index)
4056349Sqs148142 {
4066349Sqs148142 	tx_desc_t desc, *desp;
4076349Sqs148142 
4086349Sqs148142 #ifdef HXGE_DEBUG
4096349Sqs148142 	uint64_t sad;
4106349Sqs148142 	int xfer_len;
4116349Sqs148142 #endif
4126349Sqs148142 
4136349Sqs148142 	HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL,
4146349Sqs148142 	    "\n==> hpi_txdma_dump_desc_one: dump "
4156349Sqs148142 	    " desc_p $%p descriptor entry %d\n", desc_p, desc_index));
4166349Sqs148142 	desc.value = 0;
4176349Sqs148142 	desp = ((desc_p != NULL) ? desc_p : (p_tx_desc_t)&desc);
418*6864Sqs148142 	HXGE_MEM_PIO_READ64(handle, &desp->value);
4196349Sqs148142 #ifdef HXGE_DEBUG
4206349Sqs148142 	sad = desp->bits.sad;
421*6864Sqs148142 	sad = (sad << 32) | desp->bits.sad_l;
4226349Sqs148142 	xfer_len = desp->bits.tr_len;
4236349Sqs148142 #endif
4246349Sqs148142 	HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL, "\n\t: value 0x%llx\n"
4256349Sqs148142 	    "\t\tsad $%p\ttr_len %d len %d\tnptrs %d\tmark %d sop %d\n",
4266349Sqs148142 	    desp->value, sad, desp->bits.tr_len, xfer_len,
4276349Sqs148142 	    desp->bits.num_ptr, desp->bits.mark, desp->bits.sop));
4286349Sqs148142 
4296349Sqs148142 	HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL,
4306349Sqs148142 	    "\n<== hpi_txdma_dump_desc_one: Done \n"));
4316349Sqs148142 }
4326349Sqs148142 
4336349Sqs148142 /*
4346349Sqs148142  * Static functions start here.
4356349Sqs148142  */
4366349Sqs148142 static hpi_status_t
hpi_txdma_control_reset_wait(hpi_handle_t handle,uint8_t channel)4376349Sqs148142 hpi_txdma_control_reset_wait(hpi_handle_t handle, uint8_t channel)
4386349Sqs148142 {
4396349Sqs148142 	tdc_tdr_cfg_t txcs;
4406349Sqs148142 	int loop = 0;
4416349Sqs148142 
4426349Sqs148142 	txcs.value = 0;
4436349Sqs148142 	do {
4446349Sqs148142 		HXGE_DELAY(TXDMA_WAIT_MSEC);
4456349Sqs148142 		TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &txcs.value);
4466349Sqs148142 
4476349Sqs148142 		/*
4486349Sqs148142 		 * Reset completes when this bit is set to 1 by hw
4496349Sqs148142 		 */
4506349Sqs148142 		if (txcs.bits.qst) {
4516349Sqs148142 			return (HPI_SUCCESS);
4526349Sqs148142 		}
4536349Sqs148142 		loop++;
4546349Sqs148142 	} while (loop < TXDMA_WAIT_LOOP);
4556349Sqs148142 
4566349Sqs148142 	if (loop == TXDMA_WAIT_LOOP) {
4576349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
4586349Sqs148142 		    "hpi_txdma_control_reset_wait: RST bit not "
4596349Sqs148142 		    "cleared to 0 txcs.bits 0x%llx", txcs.value));
4606349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_RESET_FAILED);
4616349Sqs148142 	}
4626349Sqs148142 	return (HPI_SUCCESS);
4636349Sqs148142 }
4646349Sqs148142 
465*6864Sqs148142 hpi_status_t
hpi_txdma_control_stop_wait(hpi_handle_t handle,uint8_t channel)4666349Sqs148142 hpi_txdma_control_stop_wait(hpi_handle_t handle, uint8_t channel)
4676349Sqs148142 {
4686349Sqs148142 	tdc_tdr_cfg_t	txcs;
4696349Sqs148142 	int		loop = 0;
4706349Sqs148142 
4716349Sqs148142 	do {
4726349Sqs148142 		txcs.value = 0;
4736349Sqs148142 		HXGE_DELAY(TXDMA_WAIT_MSEC);
4746349Sqs148142 		TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &txcs.value);
4756349Sqs148142 		if (txcs.bits.qst) {
4766349Sqs148142 			return (HPI_SUCCESS);
4776349Sqs148142 		}
4786349Sqs148142 		loop++;
4796349Sqs148142 	} while (loop < TXDMA_WAIT_LOOP);
4806349Sqs148142 
4816349Sqs148142 	if (loop == TXDMA_WAIT_LOOP) {
4826349Sqs148142 		HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
4836349Sqs148142 		    "hpi_txdma_control_stop_wait: SNG_STATE not "
4846349Sqs148142 		    "set to 1 txcs.bits 0x%llx", txcs.value));
4856349Sqs148142 		return (HPI_FAILURE | HPI_TXDMA_STOP_FAILED);
4866349Sqs148142 	}
4876349Sqs148142 	return (HPI_SUCCESS);
4886349Sqs148142 }
489