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 /*
22cf6ef894SMichael Speer  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
233dec9fcdSqs  * Use is subject to license terms.
243dec9fcdSqs  */
253dec9fcdSqs 
263dec9fcdSqs #ifndef	_SYS_HXGE_HXGE_TXDMA_H
273dec9fcdSqs #define	_SYS_HXGE_HXGE_TXDMA_H
283dec9fcdSqs 
293dec9fcdSqs #ifdef	__cplusplus
303dec9fcdSqs extern "C" {
313dec9fcdSqs #endif
323dec9fcdSqs 
33*1ed83081SMichael Speer #include <sys/taskq.h>
343dec9fcdSqs #include <hxge_txdma_hw.h>
353dec9fcdSqs #include <hpi_txdma.h>
363dec9fcdSqs 
373dec9fcdSqs #define	TXDMA_RECLAIM_PENDING_DEFAULT		64
383dec9fcdSqs #define	TX_FULL_MARK				3
393dec9fcdSqs 
403dec9fcdSqs /*
413dec9fcdSqs  * Transmit load balancing definitions.
423dec9fcdSqs  */
433dec9fcdSqs #define	HXGE_TX_LB_TCPUDP	0	/* default policy */
443dec9fcdSqs #define	HXGE_TX_LB_HASH		1	/* from the hint data */
453dec9fcdSqs #define	HXGE_TX_LB_DEST_MAC	2	/* Dest. MAC */
463dec9fcdSqs 
473dec9fcdSqs /*
483dec9fcdSqs  * Descriptor ring empty:
493dec9fcdSqs  *		(1) head index is equal to tail index.
503dec9fcdSqs  *		(2) wrapped around bits are the same.
513dec9fcdSqs  * Descriptor ring full:
523dec9fcdSqs  *		(1) head index is equal to tail index.
533dec9fcdSqs  *		(2) wrapped around bits are different.
543dec9fcdSqs  *
553dec9fcdSqs  */
563dec9fcdSqs #define	TXDMA_RING_EMPTY(head, head_wrap, tail, tail_wrap)	\
573dec9fcdSqs 	((head == tail && head_wrap == tail_wrap) ? B_TRUE : B_FALSE)
583dec9fcdSqs 
593dec9fcdSqs #define	TXDMA_RING_FULL(head, head_wrap, tail, tail_wrap)	\
603dec9fcdSqs 	((head == tail && head_wrap != tail_wrap) ? B_TRUE : B_FALSE)
613dec9fcdSqs 
623dec9fcdSqs #define	TXDMA_DESC_NEXT_INDEX(index, entries, wrap_mask) \
633dec9fcdSqs 			((index + entries) & wrap_mask)
643dec9fcdSqs 
653dec9fcdSqs typedef struct _tx_msg_t {
663dec9fcdSqs 	hxge_os_block_mv_t	flags;		/* DMA, BCOPY, DVMA (?) */
673dec9fcdSqs 	hxge_os_dma_common_t	buf_dma;	/* premapped buffer blocks */
683dec9fcdSqs 	hxge_os_dma_handle_t	buf_dma_handle;	/* premapped buffer handle */
693dec9fcdSqs 	hxge_os_dma_handle_t	dma_handle;	/* DMA handle for normal send */
703dec9fcdSqs 	hxge_os_dma_handle_t	dvma_handle;	/* Fast DVMA  handle */
713dec9fcdSqs 
723dec9fcdSqs 	p_mblk_t		tx_message;
733dec9fcdSqs 	uint32_t		tx_msg_size;
743dec9fcdSqs 	size_t			bytes_used;
753dec9fcdSqs 	int			head;
763dec9fcdSqs 	int			tail;
77cf6ef894SMichael Speer 	int			offset_index;
783dec9fcdSqs } tx_msg_t, *p_tx_msg_t;
793dec9fcdSqs 
803dec9fcdSqs /*
813dec9fcdSqs  * TX  Statistics.
823dec9fcdSqs  */
833dec9fcdSqs typedef struct _hxge_tx_ring_stats_t {
843dec9fcdSqs 	uint64_t		opackets;
853dec9fcdSqs 	uint64_t		obytes;
863dec9fcdSqs 	uint64_t		obytes_with_pad;
873dec9fcdSqs 	uint64_t		oerrors;
883dec9fcdSqs 
893dec9fcdSqs 	uint32_t		tx_inits;
903dec9fcdSqs 	uint32_t		tx_no_buf;
913dec9fcdSqs 
923dec9fcdSqs 	uint32_t		peu_resp_err;
933dec9fcdSqs 	uint32_t		pkt_size_hdr_err;
943dec9fcdSqs 	uint32_t		runt_pkt_drop_err;
953dec9fcdSqs 	uint32_t		pkt_size_err;
963dec9fcdSqs 	uint32_t		tx_rng_oflow;
973dec9fcdSqs 	uint32_t		pref_par_err;
983dec9fcdSqs 	uint32_t		tdr_pref_cpl_to;
993dec9fcdSqs 	uint32_t		pkt_cpl_to;
1003dec9fcdSqs 	uint32_t		invalid_sop;
1013dec9fcdSqs 	uint32_t		unexpected_sop;
1023dec9fcdSqs 
1033dec9fcdSqs 	uint64_t		count_hdr_size_err;
1043dec9fcdSqs 	uint64_t		count_runt;
1053dec9fcdSqs 	uint64_t		count_abort;
1063dec9fcdSqs 
1073dec9fcdSqs 	uint32_t		tx_starts;
1083dec9fcdSqs 	uint32_t		tx_no_desc;
1093dec9fcdSqs 	uint32_t		tx_dma_bind_fail;
1103dec9fcdSqs 	uint32_t		tx_hdr_pkts;
1113dec9fcdSqs 	uint32_t		tx_ddi_pkts;
1123dec9fcdSqs 	uint32_t		tx_jumbo_pkts;
1133dec9fcdSqs 	uint32_t		tx_max_pend;
1143dec9fcdSqs 	uint32_t		tx_marks;
1153dec9fcdSqs 	tdc_pref_par_log_t	errlog;
1163dec9fcdSqs } hxge_tx_ring_stats_t, *p_hxge_tx_ring_stats_t;
1173dec9fcdSqs 
1183dec9fcdSqs typedef struct _hxge_tdc_sys_stats {
1193dec9fcdSqs 	uint32_t	reord_tbl_par_err;
1203dec9fcdSqs 	uint32_t	reord_buf_ded_err;
1213dec9fcdSqs 	uint32_t	reord_buf_sec_err;
1223dec9fcdSqs } hxge_tdc_sys_stats_t, *p_hxge_tdc_sys_stats_t;
1233dec9fcdSqs 
1243dec9fcdSqs typedef struct _tx_ring_t {
1253dec9fcdSqs 	hxge_os_dma_common_t	tdc_desc;
1263dec9fcdSqs 	struct _hxge_t		*hxgep;
127*1ed83081SMichael Speer 	mac_ring_handle_t	ring_handle;
128*1ed83081SMichael Speer 	ddi_taskq_t		*taskq;
1293dec9fcdSqs 	p_tx_msg_t		tx_msg_ring;
1303dec9fcdSqs 	uint32_t		tnblocks;
1313dec9fcdSqs 	tdc_tdr_cfg_t		tx_ring_cfig;
1323dec9fcdSqs 	tdc_tdr_kick_t		tx_ring_kick;
1333dec9fcdSqs 	tdc_tdr_cfg_t		tx_cs;
1343dec9fcdSqs 	tdc_int_mask_t		tx_evmask;
1353dec9fcdSqs 	tdc_mbh_t		tx_mbox_mbh;
1363dec9fcdSqs 	tdc_mbl_t		tx_mbox_mbl;
1373dec9fcdSqs 
1383dec9fcdSqs 	tdc_page_handle_t	page_hdl;
1393dec9fcdSqs 
1403dec9fcdSqs 	hxge_os_mutex_t		lock;
1413dec9fcdSqs 	uint16_t		index;
1423dec9fcdSqs 	uint16_t		tdc;
1433dec9fcdSqs 	struct hxge_tdc_cfg	*tdc_p;
1443dec9fcdSqs 	uint_t			tx_ring_size;
1453dec9fcdSqs 	uint32_t		num_chunks;
1463dec9fcdSqs 
1473dec9fcdSqs 	uint_t			tx_wrap_mask;
1483dec9fcdSqs 	uint_t			rd_index;
1493dec9fcdSqs 	uint_t			wr_index;
1503dec9fcdSqs 	boolean_t		wr_index_wrap;
1513dec9fcdSqs 	uint_t			head_index;
1523dec9fcdSqs 	boolean_t		head_wrap;
1533dec9fcdSqs 	tdc_tdr_head_t		ring_head;
1543dec9fcdSqs 	tdc_tdr_kick_t		ring_kick_tail;
1553dec9fcdSqs 	txdma_mailbox_t		tx_mbox;
1563dec9fcdSqs 
1573dec9fcdSqs 	uint_t			descs_pending;
1583dec9fcdSqs 	boolean_t		queueing;
1593dec9fcdSqs 
1603dec9fcdSqs 	p_mblk_t		head;
1613dec9fcdSqs 	p_mblk_t		tail;
1623dec9fcdSqs 
1633dec9fcdSqs 	p_hxge_tx_ring_stats_t	tdc_stats;
1643dec9fcdSqs 
1653dec9fcdSqs 	uint_t			dvma_wr_index;
1663dec9fcdSqs 	uint_t			dvma_rd_index;
1673dec9fcdSqs 	uint_t			dvma_pending;
1683dec9fcdSqs 	uint_t			dvma_available;
1693dec9fcdSqs 	uint_t			dvma_wrap_mask;
1703dec9fcdSqs 
1713dec9fcdSqs 	hxge_os_dma_handle_t	*dvma_ring;
1723dec9fcdSqs 
1733dec9fcdSqs 	mac_resource_handle_t	tx_mac_resource_handle;
1743dec9fcdSqs } tx_ring_t, *p_tx_ring_t;
1753dec9fcdSqs 
1763dec9fcdSqs 
1773dec9fcdSqs /* Transmit Mailbox */
1783dec9fcdSqs typedef struct _tx_mbox_t {
1793dec9fcdSqs 	hxge_os_mutex_t		lock;
1803dec9fcdSqs 	uint16_t		index;
1813dec9fcdSqs 	struct _hxge_t		*hxgep;
1823dec9fcdSqs 	uint16_t		tdc;
1833dec9fcdSqs 	hxge_os_dma_common_t	tx_mbox;
1843dec9fcdSqs 	tdc_mbl_t		tx_mbox_l;
1853dec9fcdSqs 	tdc_mbh_t		tx_mbox_h;
1863dec9fcdSqs } tx_mbox_t, *p_tx_mbox_t;
1873dec9fcdSqs 
1883dec9fcdSqs typedef struct _tx_rings_t {
1893dec9fcdSqs 	p_tx_ring_t		*rings;
1903dec9fcdSqs 	boolean_t		txdesc_allocated;
1913dec9fcdSqs 	uint32_t		ndmas;
1923dec9fcdSqs 	hxge_os_dma_common_t	tdc_dma;
1933dec9fcdSqs 	hxge_os_dma_common_t	tdc_mbox;
1943dec9fcdSqs } tx_rings_t, *p_tx_rings_t;
1953dec9fcdSqs 
1963dec9fcdSqs typedef struct _tx_mbox_areas_t {
1973dec9fcdSqs 	p_tx_mbox_t		*txmbox_areas_p;
1983dec9fcdSqs 	boolean_t		txmbox_allocated;
1993dec9fcdSqs } tx_mbox_areas_t, *p_tx_mbox_areas_t;
2003dec9fcdSqs 
2013dec9fcdSqs /*
2023dec9fcdSqs  * Transmit prototypes.
2033dec9fcdSqs  */
2043dec9fcdSqs hxge_status_t hxge_init_txdma_channels(p_hxge_t hxgep);
2053dec9fcdSqs void hxge_uninit_txdma_channels(p_hxge_t hxgep);
2063dec9fcdSqs void hxge_setup_dma_common(p_hxge_dma_common_t, p_hxge_dma_common_t,
2073dec9fcdSqs 	uint32_t, uint32_t);
2083dec9fcdSqs hxge_status_t hxge_reset_txdma_channel(p_hxge_t hxgep, uint16_t channel,
2093dec9fcdSqs 	uint64_t reg_data);
2103dec9fcdSqs hxge_status_t hxge_init_txdma_channel_event_mask(p_hxge_t hxgep,
2113dec9fcdSqs 	uint16_t channel, tdc_int_mask_t *mask_p);
2123dec9fcdSqs hxge_status_t hxge_enable_txdma_channel(p_hxge_t hxgep, uint16_t channel,
2133dec9fcdSqs 	p_tx_ring_t tx_desc_p, p_tx_mbox_t mbox_p);
2143dec9fcdSqs 
2153dec9fcdSqs p_mblk_t hxge_tx_pkt_header_reserve(p_mblk_t mp, uint8_t *npads);
2163dec9fcdSqs 	int hxge_tx_pkt_nmblocks(p_mblk_t mp, int *tot_xfer_len_p);
2173dec9fcdSqs boolean_t hxge_txdma_reclaim(p_hxge_t hxgep,
2183dec9fcdSqs 	p_tx_ring_t tx_ring_p, int nmblks);
2193dec9fcdSqs 
2203dec9fcdSqs void hxge_fill_tx_hdr(p_mblk_t mp, boolean_t fill_len, boolean_t l4_cksum,
2213dec9fcdSqs 	int pkt_len, uint8_t npads, p_tx_pkt_hdr_all_t pkthdrp);
2223dec9fcdSqs 
2233dec9fcdSqs hxge_status_t hxge_txdma_hw_mode(p_hxge_t hxgep, boolean_t enable);
2243dec9fcdSqs void hxge_txdma_stop(p_hxge_t hxgep);
2253dec9fcdSqs void hxge_fixup_txdma_rings(p_hxge_t hxgep);
2263dec9fcdSqs void hxge_txdma_hw_kick(p_hxge_t hxgep);
2273dec9fcdSqs void hxge_txdma_fix_channel(p_hxge_t hxgep, uint16_t channel);
2283dec9fcdSqs void hxge_txdma_fixup_channel(p_hxge_t hxgep, p_tx_ring_t ring_p,
2293dec9fcdSqs 	uint16_t channel);
2303dec9fcdSqs void hxge_txdma_hw_kick_channel(p_hxge_t hxgep, p_tx_ring_t ring_p,
2313dec9fcdSqs 	uint16_t channel);
2323dec9fcdSqs 
2333dec9fcdSqs void hxge_check_tx_hang(p_hxge_t hxgep);
2343dec9fcdSqs void hxge_fixup_hung_txdma_rings(p_hxge_t hxgep);
2353dec9fcdSqs void hxge_txdma_fix_hung_channel(p_hxge_t hxgep, uint16_t channel);
2363dec9fcdSqs void hxge_txdma_fixup_hung_channel(p_hxge_t hxgep, p_tx_ring_t ring_p,
2373dec9fcdSqs 	uint16_t channel);
2383dec9fcdSqs 
239*1ed83081SMichael Speer mblk_t *hxge_tx_ring_send(void *arg, mblk_t *mp);
2403dec9fcdSqs void hxge_reclaim_rings(p_hxge_t hxgep);
2413dec9fcdSqs int hxge_txdma_channel_hung(p_hxge_t hxgep,
2423dec9fcdSqs 	p_tx_ring_t tx_ring_p, uint16_t channel);
2433dec9fcdSqs int hxge_txdma_hung(p_hxge_t hxgep);
2443dec9fcdSqs int hxge_txdma_stop_inj_err(p_hxge_t hxgep, int channel);
2453dec9fcdSqs hxge_status_t hxge_txdma_handle_sys_errors(p_hxge_t hxgep);
2463dec9fcdSqs 
2473dec9fcdSqs #ifdef	__cplusplus
2483dec9fcdSqs }
2493dec9fcdSqs #endif
2503dec9fcdSqs 
2513dec9fcdSqs #endif /* _SYS_HXGE_HXGE_TXDMA_H */
252