xref: /onnv-gate/usr/src/uts/common/io/xge/hal/xgehal/xgehal-ring-fp.c (revision 6937:a5e2c8b5c817)
11256Syl150051 /*
21256Syl150051  * CDDL HEADER START
31256Syl150051  *
41256Syl150051  * The contents of this file are subject to the terms of the
51256Syl150051  * Common Development and Distribution License (the "License").
61256Syl150051  * You may not use this file except in compliance with the License.
71256Syl150051  *
81256Syl150051  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91256Syl150051  * or http://www.opensolaris.org/os/licensing.
101256Syl150051  * See the License for the specific language governing permissions
111256Syl150051  * and limitations under the License.
121256Syl150051  *
131256Syl150051  * When distributing Covered Code, include this CDDL HEADER in each
141256Syl150051  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151256Syl150051  * If applicable, add the following below this CDDL HEADER, with the
161256Syl150051  * fields enclosed by brackets "[]" replaced with your own identifying
171256Syl150051  * information: Portions Copyright [yyyy] [name of copyright owner]
181256Syl150051  *
191256Syl150051  * CDDL HEADER END
201256Syl150051  *
213115Syl150051  * Copyright (c) 2002-2006 Neterion, Inc.
221256Syl150051  */
231256Syl150051 
241256Syl150051 #ifdef XGE_DEBUG_FP
251256Syl150051 #include "xgehal-ring.h"
261256Syl150051 #endif
271256Syl150051 
283115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	xge_hal_ring_rxd_priv_t*
__hal_ring_rxd_priv(xge_hal_ring_t * ring,xge_hal_dtr_h dtrh)293115Syl150051 __hal_ring_rxd_priv(xge_hal_ring_t *ring, xge_hal_dtr_h	dtrh)
301256Syl150051 {
311256Syl150051 
321256Syl150051 	xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
333115Syl150051 	xge_hal_ring_rxd_priv_t	*rxd_priv;
341256Syl150051 
351256Syl150051 	xge_assert(rxdp);
361256Syl150051 
373115Syl150051 #if	defined(XGE_HAL_USE_5B_MODE)
381256Syl150051 	xge_assert(ring);
391256Syl150051 	if (ring->buffer_mode == XGE_HAL_RING_QUEUE_BUFFER_MODE_5) {
401256Syl150051 		xge_hal_ring_rxd_5_t *rxdp_5 = (xge_hal_ring_rxd_5_t *)dtrh;
413115Syl150051 #if	defined	(XGE_OS_PLATFORM_64BIT)
423115Syl150051 		int	memblock_idx = rxdp_5->host_control	>> 16;
433115Syl150051 		int	i =	rxdp_5->host_control & 0xFFFF;
443115Syl150051 		rxd_priv = (xge_hal_ring_rxd_priv_t	*)
453115Syl150051 			((char*)ring->mempool->memblocks_priv_arr[memblock_idx]	+ ring->rxd_priv_size *	i);
461256Syl150051 #else
471256Syl150051 		/* 32-bit case */
483115Syl150051 		rxd_priv = (xge_hal_ring_rxd_priv_t	*)rxdp_5->host_control;
491256Syl150051 #endif
501256Syl150051 	} else
511256Syl150051 #endif
521256Syl150051 	{
533115Syl150051 		rxd_priv = (xge_hal_ring_rxd_priv_t	*)
541256Syl150051 				(ulong_t)rxdp->host_control;
551256Syl150051 	}
561256Syl150051 
571256Syl150051 	xge_assert(rxd_priv);
581256Syl150051 	xge_assert(rxd_priv->dma_object);
591256Syl150051 
603115Syl150051 	xge_assert(rxd_priv->dma_object->handle	== rxd_priv->dma_handle);
611256Syl150051 
623115Syl150051 	xge_assert(rxd_priv->dma_object->addr +	rxd_priv->dma_offset ==
631256Syl150051 							rxd_priv->dma_addr);
641256Syl150051 
651256Syl150051 	return rxd_priv;
661256Syl150051 }
671256Syl150051 
683115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	int
__hal_ring_block_memblock_idx(xge_hal_ring_block_t * block)691256Syl150051 __hal_ring_block_memblock_idx(xge_hal_ring_block_t *block)
701256Syl150051 {
713115Syl150051 	   return (int)*((u64 *)(void *)((char *)block +
723115Syl150051 							   XGE_HAL_RING_MEMBLOCK_IDX_OFFSET));
731256Syl150051 }
741256Syl150051 
753115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
__hal_ring_block_memblock_idx_set(xge_hal_ring_block_t * block,int memblock_idx)761256Syl150051 __hal_ring_block_memblock_idx_set(xge_hal_ring_block_t*block, int memblock_idx)
771256Syl150051 {
783115Syl150051 	   *((u64 *)(void *)((char *)block +
793115Syl150051 					   XGE_HAL_RING_MEMBLOCK_IDX_OFFSET)) =
803115Syl150051 					   memblock_idx;
811256Syl150051 }
821256Syl150051 
831256Syl150051 
843115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	dma_addr_t
__hal_ring_block_next_pointer(xge_hal_ring_block_t * block)851256Syl150051 __hal_ring_block_next_pointer(xge_hal_ring_block_t *block)
861256Syl150051 {
871256Syl150051 	return (dma_addr_t)*((u64 *)(void *)((char *)block +
881256Syl150051 			XGE_HAL_RING_NEXT_BLOCK_POINTER_OFFSET));
891256Syl150051 }
901256Syl150051 
913115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
__hal_ring_block_next_pointer_set(xge_hal_ring_block_t * block,dma_addr_t dma_next)921256Syl150051 __hal_ring_block_next_pointer_set(xge_hal_ring_block_t *block,
931256Syl150051 			dma_addr_t dma_next)
941256Syl150051 {
953115Syl150051 	*((u64 *)(void *)((char	*)block	+
961256Syl150051 			  XGE_HAL_RING_NEXT_BLOCK_POINTER_OFFSET)) = dma_next;
971256Syl150051 }
981256Syl150051 
991256Syl150051 /**
1003115Syl150051  * xge_hal_ring_dtr_private	- Get ULD private per-descriptor data.
1011256Syl150051  * @channelh: Channel handle.
1021256Syl150051  * @dtrh: Descriptor handle.
1031256Syl150051  *
1043115Syl150051  * Returns:	private	ULD	info associated	with the descriptor.
1053115Syl150051  * ULD requests	per-descriptor space via xge_hal_channel_open().
1061256Syl150051  *
1071256Syl150051  * See also: xge_hal_fifo_dtr_private().
1081256Syl150051  * Usage: See ex_rx_compl{}.
1091256Syl150051  */
1103115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void*
xge_hal_ring_dtr_private(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh)1111256Syl150051 xge_hal_ring_dtr_private(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh)
1121256Syl150051 {
1133115Syl150051 	return (char *)__hal_ring_rxd_priv((xge_hal_ring_t *) channelh,	dtrh) +
1141256Syl150051 					sizeof(xge_hal_ring_rxd_priv_t);
1151256Syl150051 }
1161256Syl150051 
1171256Syl150051 /**
1183115Syl150051  * xge_hal_ring_dtr_reserve	- Reserve ring descriptor.
1191256Syl150051  * @channelh: Channel handle.
1203115Syl150051  * @dtrh: Reserved descriptor. On success HAL fills	this "out" parameter
1213115Syl150051  *		  with a valid handle.
1221256Syl150051  *
1233115Syl150051  * Reserve Rx descriptor for the subsequent	filling-in (by upper layer
1243115Syl150051  * driver (ULD)) and posting on	the	corresponding channel (@channelh)
1251256Syl150051  * via xge_hal_ring_dtr_post().
1261256Syl150051  *
1273115Syl150051  * Returns:	XGE_HAL_OK - success.
1283115Syl150051  * XGE_HAL_INF_OUT_OF_DESCRIPTORS -	Currently no descriptors available.
1291256Syl150051  *
1301256Syl150051  * See also: xge_hal_fifo_dtr_reserve(), xge_hal_ring_dtr_free(),
1311256Syl150051  * xge_hal_fifo_dtr_reserve_sp(), xge_hal_status_e{}.
1321256Syl150051  * Usage: See ex_post_all_rx{}.
1331256Syl150051  */
1343115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	xge_hal_status_e
xge_hal_ring_dtr_reserve(xge_hal_channel_h channelh,xge_hal_dtr_h * dtrh)1351256Syl150051 xge_hal_ring_dtr_reserve(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh)
1361256Syl150051 {
1371256Syl150051 	xge_hal_status_e status;
1383115Syl150051 #if	defined(XGE_HAL_RX_MULTI_RESERVE_IRQ)
1391256Syl150051 	unsigned long flags;
1401256Syl150051 #endif
1411256Syl150051 
1423115Syl150051 #if	defined(XGE_HAL_RX_MULTI_RESERVE)
1431256Syl150051 	xge_os_spin_lock(&((xge_hal_channel_t*)channelh)->reserve_lock);
1441256Syl150051 #elif defined(XGE_HAL_RX_MULTI_RESERVE_IRQ)
1451256Syl150051 	xge_os_spin_lock_irq(&((xge_hal_channel_t*)channelh)->reserve_lock,
1461256Syl150051 	flags);
1471256Syl150051 #endif
1481256Syl150051 
1491256Syl150051 	status = __hal_channel_dtr_alloc(channelh, dtrh);
1501256Syl150051 
1513115Syl150051 #if	defined(XGE_HAL_RX_MULTI_RESERVE)
1521256Syl150051 	xge_os_spin_unlock(&((xge_hal_channel_t*)channelh)->reserve_lock);
1531256Syl150051 #elif defined(XGE_HAL_RX_MULTI_RESERVE_IRQ)
1541256Syl150051 	xge_os_spin_unlock_irq(&((xge_hal_channel_t*)channelh)->reserve_lock,
1553115Syl150051 				 flags);
1561256Syl150051 #endif
1571256Syl150051 
1581256Syl150051 	if (status == XGE_HAL_OK) {
1591256Syl150051 		xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)*dtrh;
1601256Syl150051 
1613115Syl150051 		/* instead of memset: reset	this RxD */
1623115Syl150051 		rxdp->control_1	= rxdp->control_2 =	0;
1631256Syl150051 
1643115Syl150051 #if	defined(XGE_OS_MEMORY_CHECK)
165*6937Sxw161283 		__hal_ring_rxd_priv((xge_hal_ring_t *) channelh, rxdp)->allocated = 1;
1661256Syl150051 #endif
1671256Syl150051 	}
1681256Syl150051 
1691256Syl150051 	return status;
1701256Syl150051 }
1711256Syl150051 
1721256Syl150051 /**
1733115Syl150051  * xge_hal_ring_dtr_info_get - Get extended	information	associated with
1741256Syl150051  * a completed receive descriptor for 1b mode.
1751256Syl150051  * @channelh: Channel handle.
1761256Syl150051  * @dtrh: Descriptor handle.
1773115Syl150051  * @ext_info: See xge_hal_dtr_info_t{}.	Returned by	HAL.
1781256Syl150051  *
1793115Syl150051  * Retrieve	extended information associated	with a completed receive descriptor.
1801256Syl150051  *
1811256Syl150051  * See also: xge_hal_dtr_info_t{}, xge_hal_ring_dtr_1b_get(),
1821256Syl150051  * xge_hal_ring_dtr_5b_get().
1831256Syl150051  */
1843115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_info_get(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh,xge_hal_dtr_info_t * ext_info)1853115Syl150051 xge_hal_ring_dtr_info_get(xge_hal_channel_h	channelh, xge_hal_dtr_h	dtrh,
1861256Syl150051 			xge_hal_dtr_info_t *ext_info)
1871256Syl150051 {
1883115Syl150051 	/* cast	to 1-buffer	mode RxD: the code below relies	on the fact
1893115Syl150051 	 * that	control_1 and control_2	are	formatted the same way.. */
1901256Syl150051 	xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
1911256Syl150051 
1921256Syl150051 	ext_info->l3_cksum = XGE_HAL_RXD_GET_L3_CKSUM(rxdp->control_1);
1931256Syl150051 	ext_info->l4_cksum = XGE_HAL_RXD_GET_L4_CKSUM(rxdp->control_1);
1943115Syl150051 		ext_info->frame	= XGE_HAL_RXD_GET_FRAME_TYPE(rxdp->control_1);
1953115Syl150051 		ext_info->proto	= XGE_HAL_RXD_GET_FRAME_PROTO(rxdp->control_1);
1961256Syl150051 	ext_info->vlan = XGE_HAL_RXD_GET_VLAN_TAG(rxdp->control_2);
1971256Syl150051 
1983115Syl150051 	/* Herc	only, a	few	extra cycles imposed on	Xena and/or
1993115Syl150051 	 * when	RTH	is not enabled.
2003115Syl150051 	 * Alternatively, could	check
2013115Syl150051 	 * xge_hal_device_check_id(), hldev->config.rth_en,	queue->rth_en */
2021256Syl150051 	ext_info->rth_it_hit = XGE_HAL_RXD_GET_RTH_IT_HIT(rxdp->control_1);
2031256Syl150051 	ext_info->rth_spdm_hit =
2041256Syl150051 	XGE_HAL_RXD_GET_RTH_SPDM_HIT(rxdp->control_1);
2053115Syl150051 	ext_info->rth_hash_type	=
2061256Syl150051 	XGE_HAL_RXD_GET_RTH_HASH_TYPE(rxdp->control_1);
2073115Syl150051 	ext_info->rth_value	= XGE_HAL_RXD_1_GET_RTH_VALUE(rxdp->control_2);
2081256Syl150051 }
2091256Syl150051 
2101256Syl150051 /**
2113115Syl150051  * xge_hal_ring_dtr_info_nb_get	- Get extended information associated
2123115Syl150051  * with	a completed	receive	descriptor for 3b or 5b
2131256Syl150051  * modes.
2141256Syl150051  * @channelh: Channel handle.
2151256Syl150051  * @dtrh: Descriptor handle.
2163115Syl150051  * @ext_info: See xge_hal_dtr_info_t{}.	Returned by	HAL.
2171256Syl150051  *
2183115Syl150051  * Retrieve	extended information associated	with a completed receive descriptor.
2191256Syl150051  *
2201256Syl150051  * See also: xge_hal_dtr_info_t{}, xge_hal_ring_dtr_1b_get(),
2213115Syl150051  *			 xge_hal_ring_dtr_5b_get().
2221256Syl150051  */
2233115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_info_nb_get(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh,xge_hal_dtr_info_t * ext_info)2241256Syl150051 xge_hal_ring_dtr_info_nb_get(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh,
2251256Syl150051 			xge_hal_dtr_info_t *ext_info)
2261256Syl150051 {
2273115Syl150051 	/* cast	to 1-buffer	mode RxD: the code below relies	on the fact
2283115Syl150051 	 * that	control_1 and control_2	are	formatted the same way.. */
2291256Syl150051 	xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
2301256Syl150051 
2311256Syl150051 	ext_info->l3_cksum = XGE_HAL_RXD_GET_L3_CKSUM(rxdp->control_1);
2321256Syl150051 	ext_info->l4_cksum = XGE_HAL_RXD_GET_L4_CKSUM(rxdp->control_1);
2333115Syl150051 		ext_info->frame	= XGE_HAL_RXD_GET_FRAME_TYPE(rxdp->control_1);
2343115Syl150051 		ext_info->proto	= XGE_HAL_RXD_GET_FRAME_PROTO(rxdp->control_1);
2353115Syl150051 		ext_info->vlan = XGE_HAL_RXD_GET_VLAN_TAG(rxdp->control_2);
2363115Syl150051 	/* Herc	only, a	few	extra cycles imposed on	Xena and/or
2373115Syl150051 	 * when	RTH	is not enabled.	Same comment as	above. */
2381256Syl150051 	ext_info->rth_it_hit = XGE_HAL_RXD_GET_RTH_IT_HIT(rxdp->control_1);
2391256Syl150051 	ext_info->rth_spdm_hit =
2401256Syl150051 	XGE_HAL_RXD_GET_RTH_SPDM_HIT(rxdp->control_1);
2413115Syl150051 	ext_info->rth_hash_type	=
2421256Syl150051 	XGE_HAL_RXD_GET_RTH_HASH_TYPE(rxdp->control_1);
2433115Syl150051 	ext_info->rth_value	= (u32)rxdp->buffer0_ptr;
2441256Syl150051 }
2451256Syl150051 
2461256Syl150051 /**
2471256Syl150051  * xge_hal_ring_dtr_1b_set - Prepare 1-buffer-mode descriptor.
2481256Syl150051  * @dtrh: Descriptor handle.
2493115Syl150051  * @dma_pointer: DMA address of	a single receive buffer	this descriptor
2503115Syl150051  *				 should	carry. Note	that by	the	time
2513115Syl150051  *				 xge_hal_ring_dtr_1b_set
2523115Syl150051  *				 is	called,	the	receive	buffer should be already mapped
2533115Syl150051  *				 to	the	corresponding Xframe device.
2541256Syl150051  * @size: Size of the receive @dma_pointer buffer.
2551256Syl150051  *
2563115Syl150051  * Prepare 1-buffer-mode Rx	descriptor for posting
2573115Syl150051  * (via	xge_hal_ring_dtr_post()).
2581256Syl150051  *
2593115Syl150051  * This	inline helper-function does	not	return any parameters and always
2601256Syl150051  * succeeds.
2611256Syl150051  *
2623115Syl150051  * See also: xge_hal_ring_dtr_3b_set(),	xge_hal_ring_dtr_5b_set().
2631256Syl150051  * Usage: See ex_post_all_rx{}.
2641256Syl150051  */
2653115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_1b_set(xge_hal_dtr_h dtrh,dma_addr_t dma_pointer,int size)2663115Syl150051 xge_hal_ring_dtr_1b_set(xge_hal_dtr_h dtrh,	dma_addr_t dma_pointer,	int	size)
2671256Syl150051 {
2681256Syl150051 	xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
2693115Syl150051 	rxdp->buffer0_ptr =	dma_pointer;
2703115Syl150051 	rxdp->control_2	&= (~XGE_HAL_RXD_1_MASK_BUFFER0_SIZE);
2713115Syl150051 	rxdp->control_2	|= XGE_HAL_RXD_1_SET_BUFFER0_SIZE(size);
272*6937Sxw161283 
273*6937Sxw161283 	xge_debug_ring(XGE_TRACE, "xge_hal_ring_dtr_1b_set: rxdp %p control_2 %p buffer0_ptr %p",
274*6937Sxw161283     			(xge_hal_ring_rxd_1_t *)dtrh,
275*6937Sxw161283                 rxdp->control_2,
276*6937Sxw161283     			rxdp->buffer0_ptr);
2771256Syl150051 }
2781256Syl150051 
2791256Syl150051 /**
2801256Syl150051  * xge_hal_ring_dtr_1b_get - Get data from the completed 1-buf
2811256Syl150051  * descriptor.
2821256Syl150051  * @channelh: Channel handle.
2831256Syl150051  * @dtrh: Descriptor handle.
2843115Syl150051  * @dma_pointer: DMA address of	a single receive buffer	_this_ descriptor
2853115Syl150051  *				 carries. Returned by HAL.
2863115Syl150051  * @pkt_length:	Length (in bytes) of the data in the buffer	pointed	by
2873115Syl150051  *				@dma_pointer. Returned by HAL.
2881256Syl150051  *
2893115Syl150051  * Retrieve	protocol data from the completed 1-buffer-mode Rx descriptor.
2903115Syl150051  * This	inline helper-function uses	completed descriptor to	populate receive
2913115Syl150051  * buffer pointer and other	"out" parameters. The function always succeeds.
2921256Syl150051  *
2933115Syl150051  * See also: xge_hal_ring_dtr_3b_get(),	xge_hal_ring_dtr_5b_get().
2941256Syl150051  * Usage: See ex_rx_compl{}.
2951256Syl150051  */
2963115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_1b_get(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh,dma_addr_t * dma_pointer,int * pkt_length)2973115Syl150051 xge_hal_ring_dtr_1b_get(xge_hal_channel_h channelh,	xge_hal_dtr_h dtrh,
2981256Syl150051 		dma_addr_t *dma_pointer, int *pkt_length)
2991256Syl150051 {
3001256Syl150051 	xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
3011256Syl150051 
3021256Syl150051 	*pkt_length = XGE_HAL_RXD_1_GET_BUFFER0_SIZE(rxdp->control_2);
3031256Syl150051 	*dma_pointer = rxdp->buffer0_ptr;
3043115Syl150051 
3053115Syl150051 	((xge_hal_channel_t *)channelh)->poll_bytes += *pkt_length;
3061256Syl150051 }
3071256Syl150051 
3081256Syl150051 /**
3091256Syl150051  * xge_hal_ring_dtr_3b_set - Prepare 3-buffer-mode descriptor.
3101256Syl150051  * @dtrh: Descriptor handle.
3113115Syl150051  * @dma_pointers: Array	of DMA addresses. Contains exactly 3 receive buffers
3123115Syl150051  *				 _this_	descriptor should carry.
3133115Syl150051  *				 Note that by the time xge_hal_ring_dtr_3b_set
3143115Syl150051  *				 is	called,	the	receive	buffers	should be mapped
3153115Syl150051  *				 to	the	corresponding Xframe device.
3163115Syl150051  * @sizes: Array of	receive	buffer sizes. Contains 3 sizes:	one	size per
3173115Syl150051  *		   buffer from @dma_pointers.
3181256Syl150051  *
3193115Syl150051  * Prepare 3-buffer-mode Rx	descriptor for posting (via
3201256Syl150051  * xge_hal_ring_dtr_post()).
3213115Syl150051  * This	inline helper-function does	not	return any parameters and always
3221256Syl150051  * succeeds.
3231256Syl150051  *
3243115Syl150051  * See also: xge_hal_ring_dtr_1b_set(),	xge_hal_ring_dtr_5b_set().
3251256Syl150051  */
3263115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_3b_set(xge_hal_dtr_h dtrh,dma_addr_t dma_pointers[],int sizes[])3273115Syl150051 xge_hal_ring_dtr_3b_set(xge_hal_dtr_h dtrh,	dma_addr_t dma_pointers[],
3283115Syl150051 			int	sizes[])
3291256Syl150051 {
3301256Syl150051 	xge_hal_ring_rxd_3_t *rxdp = (xge_hal_ring_rxd_3_t *)dtrh;
3313115Syl150051 	rxdp->buffer0_ptr =	dma_pointers[0];
3323115Syl150051 	rxdp->control_2	&= (~XGE_HAL_RXD_3_MASK_BUFFER0_SIZE);
3333115Syl150051 	rxdp->control_2	|= XGE_HAL_RXD_3_SET_BUFFER0_SIZE(sizes[0]);
3343115Syl150051 	rxdp->buffer1_ptr =	dma_pointers[1];
3353115Syl150051 	rxdp->control_2	&= (~XGE_HAL_RXD_3_MASK_BUFFER1_SIZE);
3363115Syl150051 	rxdp->control_2	|= XGE_HAL_RXD_3_SET_BUFFER1_SIZE(sizes[1]);
3373115Syl150051 	rxdp->buffer2_ptr =	dma_pointers[2];
3383115Syl150051 	rxdp->control_2	&= (~XGE_HAL_RXD_3_MASK_BUFFER2_SIZE);
3393115Syl150051 	rxdp->control_2	|= XGE_HAL_RXD_3_SET_BUFFER2_SIZE(sizes[2]);
3401256Syl150051 }
3411256Syl150051 
3421256Syl150051 /**
3431256Syl150051  * xge_hal_ring_dtr_3b_get - Get data from the completed 3-buf
3441256Syl150051  * descriptor.
3451256Syl150051  * @channelh: Channel handle.
3461256Syl150051  * @dtrh: Descriptor handle.
3473115Syl150051  * @dma_pointers: DMA addresses	of the 3 receive buffers _this_	descriptor
3483115Syl150051  *				  carries. The first two buffers contain ethernet and
3493115Syl150051  *				  (IP +	transport) headers.	The	3rd	buffer contains	packet
3503115Syl150051  *				  data.
3513115Syl150051  *				  Returned by HAL.
3523115Syl150051  * @sizes: Array of	receive	buffer sizes. Contains 3 sizes:	one	size per
3531256Syl150051  * buffer from @dma_pointers. Returned by HAL.
3541256Syl150051  *
3553115Syl150051  * Retrieve	protocol data from the completed 3-buffer-mode Rx descriptor.
3563115Syl150051  * This	inline helper-function uses	completed descriptor to	populate receive
3573115Syl150051  * buffer pointer and other	"out" parameters. The function always succeeds.
3581256Syl150051  *
3593115Syl150051  * See also: xge_hal_ring_dtr_3b_get(),	xge_hal_ring_dtr_5b_get().
3601256Syl150051  */
3613115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_3b_get(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh,dma_addr_t dma_pointers[],int sizes[])3623115Syl150051 xge_hal_ring_dtr_3b_get(xge_hal_channel_h channelh,	xge_hal_dtr_h dtrh,
3631256Syl150051 		dma_addr_t dma_pointers[], int sizes[])
3641256Syl150051 {
3651256Syl150051 	xge_hal_ring_rxd_3_t *rxdp = (xge_hal_ring_rxd_3_t *)dtrh;
3661256Syl150051 
3673115Syl150051 	dma_pointers[0]	= rxdp->buffer0_ptr;
3681256Syl150051 	sizes[0] = XGE_HAL_RXD_3_GET_BUFFER0_SIZE(rxdp->control_2);
3691256Syl150051 
3703115Syl150051 	dma_pointers[1]	= rxdp->buffer1_ptr;
3711256Syl150051 	sizes[1] = XGE_HAL_RXD_3_GET_BUFFER1_SIZE(rxdp->control_2);
3721256Syl150051 
3733115Syl150051 	dma_pointers[2]	= rxdp->buffer2_ptr;
3741256Syl150051 	sizes[2] = XGE_HAL_RXD_3_GET_BUFFER2_SIZE(rxdp->control_2);
3753115Syl150051 
3763115Syl150051 	((xge_hal_channel_t *)channelh)->poll_bytes += sizes[0] + sizes[1] +
3773115Syl150051 		sizes[2];
3781256Syl150051 }
3791256Syl150051 
3801256Syl150051 /**
3811256Syl150051  * xge_hal_ring_dtr_5b_set - Prepare 5-buffer-mode descriptor.
3821256Syl150051  * @dtrh: Descriptor handle.
3833115Syl150051  * @dma_pointers: Array	of DMA addresses. Contains exactly 5 receive buffers
3843115Syl150051  *				 _this_	descriptor should carry.
3853115Syl150051  *				 Note that by the time xge_hal_ring_dtr_5b_set
3863115Syl150051  *				 is	called,	the	receive	buffers	should be mapped
3873115Syl150051  *				 to	the	corresponding Xframe device.
3883115Syl150051  * @sizes: Array of	receive	buffer sizes. Contains 5 sizes:	one	size per
3893115Syl150051  *		   buffer from @dma_pointers.
3901256Syl150051  *
3913115Syl150051  * Prepare 3-buffer-mode Rx	descriptor for posting (via
3921256Syl150051  * xge_hal_ring_dtr_post()).
3933115Syl150051  * This	inline helper-function does	not	return any parameters and always
3941256Syl150051  * succeeds.
3951256Syl150051  *
3963115Syl150051  * See also: xge_hal_ring_dtr_1b_set(),	xge_hal_ring_dtr_3b_set().
3971256Syl150051  */
3983115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_5b_set(xge_hal_dtr_h dtrh,dma_addr_t dma_pointers[],int sizes[])3993115Syl150051 xge_hal_ring_dtr_5b_set(xge_hal_dtr_h dtrh,	dma_addr_t dma_pointers[],
4003115Syl150051 			int	sizes[])
4011256Syl150051 {
4021256Syl150051 	xge_hal_ring_rxd_5_t *rxdp = (xge_hal_ring_rxd_5_t *)dtrh;
4033115Syl150051 	rxdp->buffer0_ptr =	dma_pointers[0];
4043115Syl150051 	rxdp->control_2	&= (~XGE_HAL_RXD_5_MASK_BUFFER0_SIZE);
4053115Syl150051 	rxdp->control_2	|= XGE_HAL_RXD_5_SET_BUFFER0_SIZE(sizes[0]);
4063115Syl150051 	rxdp->buffer1_ptr =	dma_pointers[1];
4073115Syl150051 	rxdp->control_2	&= (~XGE_HAL_RXD_5_MASK_BUFFER1_SIZE);
4083115Syl150051 	rxdp->control_2	|= XGE_HAL_RXD_5_SET_BUFFER1_SIZE(sizes[1]);
4093115Syl150051 	rxdp->buffer2_ptr =	dma_pointers[2];
4103115Syl150051 	rxdp->control_2	&= (~XGE_HAL_RXD_5_MASK_BUFFER2_SIZE);
4113115Syl150051 	rxdp->control_2	|= XGE_HAL_RXD_5_SET_BUFFER2_SIZE(sizes[2]);
4123115Syl150051 	rxdp->buffer3_ptr =	dma_pointers[3];
4133115Syl150051 	rxdp->control_3	&= (~XGE_HAL_RXD_5_MASK_BUFFER3_SIZE);
4143115Syl150051 	rxdp->control_3	|= XGE_HAL_RXD_5_SET_BUFFER3_SIZE(sizes[3]);
4153115Syl150051 	rxdp->buffer4_ptr =	dma_pointers[4];
4163115Syl150051 	rxdp->control_3	&= (~XGE_HAL_RXD_5_MASK_BUFFER4_SIZE);
4173115Syl150051 	rxdp->control_3 |= XGE_HAL_RXD_5_SET_BUFFER4_SIZE(sizes[4]);
4181256Syl150051 }
4191256Syl150051 
4201256Syl150051 /**
4211256Syl150051  * xge_hal_ring_dtr_5b_get - Get data from the completed 5-buf
4221256Syl150051  * descriptor.
4231256Syl150051  * @channelh: Channel handle.
4241256Syl150051  * @dtrh: Descriptor handle.
4253115Syl150051  * @dma_pointers: DMA addresses	of the 5 receive buffers _this_	descriptor
4263115Syl150051  *				  carries. The first 4 buffers contains	L2 (ethernet) through
4273115Syl150051  *				  L5 headers. The 5th buffer contain received (applicaion)
4283115Syl150051  *				  data.	Returned by	HAL.
4293115Syl150051  * @sizes: Array of	receive	buffer sizes. Contains 5 sizes:	one	size per
4301256Syl150051  * buffer from @dma_pointers. Returned by HAL.
4311256Syl150051  *
4323115Syl150051  * Retrieve	protocol data from the completed 5-buffer-mode Rx descriptor.
4333115Syl150051  * This	inline helper-function uses	completed descriptor to	populate receive
4343115Syl150051  * buffer pointer and other	"out" parameters. The function always succeeds.
4351256Syl150051  *
4363115Syl150051  * See also: xge_hal_ring_dtr_3b_get(),	xge_hal_ring_dtr_5b_get().
4371256Syl150051  */
4383115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_5b_get(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh,dma_addr_t dma_pointers[],int sizes[])4393115Syl150051 xge_hal_ring_dtr_5b_get(xge_hal_channel_h channelh,	xge_hal_dtr_h dtrh,
4401256Syl150051 		dma_addr_t dma_pointers[], int sizes[])
4411256Syl150051 {
4421256Syl150051 	xge_hal_ring_rxd_5_t *rxdp = (xge_hal_ring_rxd_5_t *)dtrh;
4431256Syl150051 
4443115Syl150051 	dma_pointers[0]	= rxdp->buffer0_ptr;
4451256Syl150051 	sizes[0] = XGE_HAL_RXD_5_GET_BUFFER0_SIZE(rxdp->control_2);
4461256Syl150051 
4473115Syl150051 	dma_pointers[1]	= rxdp->buffer1_ptr;
4481256Syl150051 	sizes[1] = XGE_HAL_RXD_5_GET_BUFFER1_SIZE(rxdp->control_2);
4491256Syl150051 
4503115Syl150051 	dma_pointers[2]	= rxdp->buffer2_ptr;
4511256Syl150051 	sizes[2] = XGE_HAL_RXD_5_GET_BUFFER2_SIZE(rxdp->control_2);
4521256Syl150051 
4533115Syl150051 	dma_pointers[3]	= rxdp->buffer3_ptr;
4541256Syl150051 	sizes[3] = XGE_HAL_RXD_5_GET_BUFFER3_SIZE(rxdp->control_3);
4551256Syl150051 
4563115Syl150051 	dma_pointers[4]	= rxdp->buffer4_ptr;
4571256Syl150051 	sizes[4] = XGE_HAL_RXD_5_GET_BUFFER4_SIZE(rxdp->control_3);
4583115Syl150051 
4593115Syl150051 	((xge_hal_channel_t *)channelh)->poll_bytes += sizes[0] + sizes[1] +
4603115Syl150051 		sizes[2] + sizes[3] + sizes[4];
4611256Syl150051 }
4621256Syl150051 
4631256Syl150051 
4641256Syl150051 /**
4653115Syl150051  * xge_hal_ring_dtr_pre_post - FIXME.
4663115Syl150051  * @channelh: Channel handle.
4673115Syl150051  * @dtrh: Descriptor handle.
4683115Syl150051  *
4693115Syl150051  * TBD
4701256Syl150051  */
4713115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_pre_post(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh)4723115Syl150051 xge_hal_ring_dtr_pre_post(xge_hal_channel_h	channelh, xge_hal_dtr_h	dtrh)
4731256Syl150051 {
4741256Syl150051 	xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
4753115Syl150051 #if	defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_DTR_STREAMING)
4763115Syl150051 	xge_hal_ring_rxd_priv_t	*priv;
4771256Syl150051 	xge_hal_ring_t *ring = (xge_hal_ring_t *)channelh;
4781256Syl150051 #endif
4793115Syl150051 #if	defined(XGE_HAL_RX_MULTI_POST_IRQ)
4801256Syl150051 	unsigned long flags;
4811256Syl150051 #endif
4821256Syl150051 
4833115Syl150051 	rxdp->control_2	|= XGE_HAL_RXD_NOT_COMPLETED;
4841256Syl150051 
4851256Syl150051 #ifdef XGE_DEBUG_ASSERT
4863115Syl150051 		/* make	sure Xena overwrites the (illegal) t_code on completion	*/
4873115Syl150051 		XGE_HAL_RXD_SET_T_CODE(rxdp->control_1,	XGE_HAL_RXD_T_CODE_UNUSED_C);
4881256Syl150051 #endif
4891256Syl150051 
490*6937Sxw161283 	xge_debug_ring(XGE_TRACE, "xge_hal_ring_dtr_pre_post: rxd 0x"XGE_OS_LLXFMT" posted %d  post_qid	%d",
4911256Syl150051 			(unsigned long long)(ulong_t)dtrh,
492*6937Sxw161283             ((xge_hal_ring_t *)channelh)->channel.post_index,
4931256Syl150051 			((xge_hal_ring_t *)channelh)->channel.post_qid);
4941256Syl150051 
4953115Syl150051 #if	defined(XGE_HAL_RX_MULTI_POST)
4961256Syl150051 	xge_os_spin_lock(&((xge_hal_channel_t*)channelh)->post_lock);
4971256Syl150051 #elif defined(XGE_HAL_RX_MULTI_POST_IRQ)
4981256Syl150051 	xge_os_spin_lock_irq(&((xge_hal_channel_t*)channelh)->post_lock,
4991256Syl150051 	flags);
5001256Syl150051 #endif
5011256Syl150051 
5023115Syl150051 #if	defined(XGE_DEBUG_ASSERT) && defined(XGE_HAL_RING_ENFORCE_ORDER)
5031256Syl150051 	{
5043115Syl150051 		xge_hal_channel_t *channel = (xge_hal_channel_t	*)channelh;
5051256Syl150051 
5063115Syl150051 		if (channel->post_index	!= 0) {
5071256Syl150051 			xge_hal_dtr_h prev_dtrh;
5083115Syl150051 			xge_hal_ring_rxd_priv_t	*rxdp_priv;
5091256Syl150051 
510*6937Sxw161283 			rxdp_priv =	__hal_ring_rxd_priv((xge_hal_ring_t*)channel, rxdp);
5113115Syl150051 			prev_dtrh =	channel->work_arr[channel->post_index -	1];
5121256Syl150051 
5133115Syl150051 			if (prev_dtrh != NULL &&
5143115Syl150051 				(rxdp_priv->dma_offset & (~0xFFF)) !=
5151256Syl150051 						rxdp_priv->dma_offset) {
5161256Syl150051 				xge_assert((char *)prev_dtrh +
5173115Syl150051 					((xge_hal_ring_t*)channel)->rxd_size ==	dtrh);
5181256Syl150051 			}
5191256Syl150051 		}
5201256Syl150051 	}
5211256Syl150051 #endif
5221256Syl150051 
5231256Syl150051 	__hal_channel_dtr_post(channelh, dtrh);
5241256Syl150051 
5253115Syl150051 #if	defined(XGE_HAL_RX_MULTI_POST)
5261256Syl150051 	xge_os_spin_unlock(&((xge_hal_channel_t*)channelh)->post_lock);
5271256Syl150051 #elif defined(XGE_HAL_RX_MULTI_POST_IRQ)
5281256Syl150051 	xge_os_spin_unlock_irq(&((xge_hal_channel_t*)channelh)->post_lock,
5293115Syl150051 				   flags);
5301256Syl150051 #endif
5311256Syl150051 }
5321256Syl150051 
5331256Syl150051 
5341256Syl150051 /**
5353115Syl150051  * xge_hal_ring_dtr_post_post -	FIXME.
5363115Syl150051  * @channelh: Channel handle.
5373115Syl150051  * @dtrh: Descriptor handle.
5383115Syl150051  *
5393115Syl150051  * TBD
5401256Syl150051  */
5413115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_post_post(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh)5421256Syl150051 xge_hal_ring_dtr_post_post(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh)
5431256Syl150051 {
5441256Syl150051 	xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
5451256Syl150051 	xge_hal_ring_t *ring = (xge_hal_ring_t *)channelh;
5463115Syl150051 #if	defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_DTR_STREAMING)
5473115Syl150051 	xge_hal_ring_rxd_priv_t	*priv;
5481256Syl150051 #endif
5491256Syl150051 	/* do POST */
5503115Syl150051 	rxdp->control_1	|= XGE_HAL_RXD_POSTED_4_XFRAME;
5511256Syl150051 
5523115Syl150051 #if	defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_DTR_STREAMING)
5531256Syl150051 	priv = __hal_ring_rxd_priv(ring, rxdp);
5541256Syl150051 	xge_os_dma_sync(ring->channel.pdev,
5553115Syl150051 				  priv->dma_handle,	priv->dma_addr,
5563115Syl150051 			  priv->dma_offset,	ring->rxd_size,
5573115Syl150051 			  XGE_OS_DMA_DIR_TODEVICE);
5581256Syl150051 #endif
559*6937Sxw161283 
560*6937Sxw161283 	xge_debug_ring(XGE_TRACE, "xge_hal_ring_dtr_post_post: rxdp %p control_1 %p",
561*6937Sxw161283         		  (xge_hal_ring_rxd_1_t *)dtrh,
562*6937Sxw161283                   rxdp->control_1);
563*6937Sxw161283 
5643115Syl150051 	if (ring->channel.usage_cnt	> 0)
5653115Syl150051 		ring->channel.usage_cnt--;
5661256Syl150051 }
5671256Syl150051 
5681256Syl150051 /**
569*6937Sxw161283  * xge_hal_ring_dtr_post_post_wmb.
570*6937Sxw161283  * @channelh: Channel handle.
571*6937Sxw161283  * @dtrh: Descriptor handle.
572*6937Sxw161283  *
573*6937Sxw161283  * Similar as xge_hal_ring_dtr_post_post, but in addition it does memory barrier.
574*6937Sxw161283  */
575*6937Sxw161283 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_post_post_wmb(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh)576*6937Sxw161283 xge_hal_ring_dtr_post_post_wmb(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh)
577*6937Sxw161283 {
578*6937Sxw161283 	xge_hal_ring_rxd_1_t *rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
579*6937Sxw161283 	xge_hal_ring_t *ring = (xge_hal_ring_t *)channelh;
580*6937Sxw161283 #if	defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_DTR_STREAMING)
581*6937Sxw161283 	xge_hal_ring_rxd_priv_t	*priv;
582*6937Sxw161283 #endif
583*6937Sxw161283     /* Do memory barrier before changing the ownership */
584*6937Sxw161283     xge_os_wmb();
585*6937Sxw161283 
586*6937Sxw161283 	/* do POST */
587*6937Sxw161283 	rxdp->control_1	|= XGE_HAL_RXD_POSTED_4_XFRAME;
588*6937Sxw161283 
589*6937Sxw161283 #if	defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_DTR_STREAMING)
590*6937Sxw161283 	priv = __hal_ring_rxd_priv(ring, rxdp);
591*6937Sxw161283 	xge_os_dma_sync(ring->channel.pdev,
592*6937Sxw161283 				  priv->dma_handle,	priv->dma_addr,
593*6937Sxw161283 			  priv->dma_offset,	ring->rxd_size,
594*6937Sxw161283 			  XGE_OS_DMA_DIR_TODEVICE);
595*6937Sxw161283 #endif
596*6937Sxw161283 
597*6937Sxw161283 	if (ring->channel.usage_cnt	> 0)
598*6937Sxw161283 		ring->channel.usage_cnt--;
599*6937Sxw161283 
600*6937Sxw161283 	xge_debug_ring(XGE_TRACE, "xge_hal_ring_dtr_post_post_wmb: rxdp %p control_1 %p rxds_with_host %d",
601*6937Sxw161283         		  (xge_hal_ring_rxd_1_t *)dtrh,
602*6937Sxw161283                   rxdp->control_1, ring->channel.usage_cnt);
603*6937Sxw161283 
604*6937Sxw161283 }
605*6937Sxw161283 
606*6937Sxw161283 /**
6073115Syl150051  * xge_hal_ring_dtr_post - Post	descriptor on the ring channel.
6081256Syl150051  * @channelh: Channel handle.
6091256Syl150051  * @dtrh: Descriptor obtained via xge_hal_ring_dtr_reserve().
6101256Syl150051  *
6113115Syl150051  * Post	descriptor on the 'ring' type channel.
6123115Syl150051  * Prior to	posting	the	descriptor should be filled	in accordance with
6133115Syl150051  * Host/Xframe interface specification for a given service (LL,	etc.).
6141256Syl150051  *
6151256Syl150051  * See also: xge_hal_fifo_dtr_post_many(), xge_hal_fifo_dtr_post().
6161256Syl150051  * Usage: See ex_post_all_rx{}.
6171256Syl150051  */
6183115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_post(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh)6193115Syl150051 xge_hal_ring_dtr_post(xge_hal_channel_h	channelh, xge_hal_dtr_h	dtrh)
6201256Syl150051 {
6213115Syl150051 	xge_hal_ring_dtr_pre_post(channelh,	dtrh);
6221256Syl150051 	xge_hal_ring_dtr_post_post(channelh, dtrh);
6231256Syl150051 }
6241256Syl150051 
6251256Syl150051 /**
6263115Syl150051  * xge_hal_ring_dtr_next_completed - Get the _next_	completed
6271256Syl150051  * descriptor.
6281256Syl150051  * @channelh: Channel handle.
6291256Syl150051  * @dtrh: Descriptor handle. Returned by HAL.
6303115Syl150051  * @t_code:	Transfer code, as per Xframe User Guide,
6313115Syl150051  *			Receive	Descriptor Format. Returned	by HAL.
6321256Syl150051  *
6333115Syl150051  * Retrieve	the	_next_ completed descriptor.
6343115Syl150051  * HAL uses	channel	callback (*xge_hal_channel_callback_f) to notifiy
6353115Syl150051  * upper-layer driver (ULD)	of new completed descriptors. After	that
6361256Syl150051  * the ULD can use xge_hal_ring_dtr_next_completed to retrieve the rest
6373115Syl150051  * completions (the	very first completion is passed	by HAL via
6381256Syl150051  * xge_hal_channel_callback_f).
6391256Syl150051  *
6403115Syl150051  * Implementation-wise,	the	upper-layer	driver is free to call
6411256Syl150051  * xge_hal_ring_dtr_next_completed either immediately from inside the
6423115Syl150051  * channel callback, or	in a deferred fashion and separate (from HAL)
6431256Syl150051  * context.
6441256Syl150051  *
6453115Syl150051  * Non-zero	@t_code	means failure to fill-in receive buffer(s)
6461256Syl150051  * of the descriptor.
6473115Syl150051  * For instance, parity	error detected during the data transfer.
6483115Syl150051  * In this case	Xframe will	complete the descriptor	and	indicate
6493115Syl150051  * for the host	that the received data is not to be	used.
6503115Syl150051  * For details please refer	to Xframe User Guide.
6511256Syl150051  *
6523115Syl150051  * Returns:	XGE_HAL_OK - success.
6533115Syl150051  * XGE_HAL_INF_NO_MORE_COMPLETED_DESCRIPTORS - No completed	descriptors
6541256Syl150051  * are currently available for processing.
6551256Syl150051  *
6561256Syl150051  * See also: xge_hal_channel_callback_f{},
6571256Syl150051  * xge_hal_fifo_dtr_next_completed(), xge_hal_status_e{}.
6581256Syl150051  * Usage: See ex_rx_compl{}.
6591256Syl150051  */
6603115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	xge_hal_status_e
xge_hal_ring_dtr_next_completed(xge_hal_channel_h channelh,xge_hal_dtr_h * dtrh,u8 * t_code)6613115Syl150051 xge_hal_ring_dtr_next_completed(xge_hal_channel_h channelh,	xge_hal_dtr_h *dtrh,
6621256Syl150051 				u8 *t_code)
6631256Syl150051 {
6643115Syl150051 	xge_hal_ring_rxd_1_t *rxdp;	/* doesn't matter 1, 3 or 5... */
6651256Syl150051 	xge_hal_ring_t *ring = (xge_hal_ring_t *)channelh;
6663115Syl150051 #if	defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_DTR_STREAMING)
6673115Syl150051 	xge_hal_ring_rxd_priv_t	*priv;
6681256Syl150051 #endif
6691256Syl150051 
6701256Syl150051 	__hal_channel_dtr_try_complete(ring, dtrh);
6711256Syl150051 	rxdp = (xge_hal_ring_rxd_1_t *)*dtrh;
6723115Syl150051 	if (rxdp ==	NULL) {
6731256Syl150051 		return XGE_HAL_INF_NO_MORE_COMPLETED_DESCRIPTORS;
6741256Syl150051 	}
6751256Syl150051 
6763115Syl150051 #if	defined(XGE_OS_DMA_REQUIRES_SYNC) && defined(XGE_HAL_DMA_DTR_STREAMING)
6773115Syl150051 	/* Note: 24	bytes at most means:
6783115Syl150051 	 *	- Control_3	in case	of 5-buffer	mode
6793115Syl150051 	 *	- Control_1	and	Control_2
6801256Syl150051 	 *
6813115Syl150051 	 * This	is the only	length needs to	be invalidated
6823115Syl150051 	 * type	of channels.*/
6831256Syl150051 	priv = __hal_ring_rxd_priv(ring, rxdp);
6841256Syl150051 	xge_os_dma_sync(ring->channel.pdev,
6853115Syl150051 				  priv->dma_handle,	priv->dma_addr,
6863115Syl150051 			  priv->dma_offset,	24,
6873115Syl150051 			  XGE_OS_DMA_DIR_FROMDEVICE);
6881256Syl150051 #endif
6891256Syl150051 
6903115Syl150051 	/* check whether it	is not the end */
6913115Syl150051 	if (!(rxdp->control_2 &	XGE_HAL_RXD_NOT_COMPLETED) &&
6923115Syl150051 		!(rxdp->control_1 &	XGE_HAL_RXD_POSTED_4_XFRAME)) {
6933115Syl150051 #ifndef	XGE_HAL_IRQ_POLLING
6943115Syl150051 		if (++ring->cmpl_cnt > ring->indicate_max_pkts)	{
6953115Syl150051 			/* reset it. since we don't	want to	return
6961256Syl150051 			 * garbage to the ULD */
6973115Syl150051 			*dtrh =	0;
6983115Syl150051 			return XGE_HAL_COMPLETIONS_REMAIN;
6991256Syl150051 		}
7001256Syl150051 #endif
7011256Syl150051 
7021256Syl150051 #ifdef XGE_DEBUG_ASSERT
7033115Syl150051 #if	defined(XGE_HAL_USE_5B_MODE)
7043115Syl150051 #if	!defined(XGE_OS_PLATFORM_64BIT)
7051256Syl150051 		if (ring->buffer_mode == XGE_HAL_RING_QUEUE_BUFFER_MODE_5) {
7061256Syl150051 			xge_assert(((xge_hal_ring_rxd_5_t *)
7071256Syl150051 					rxdp)->host_control!=0);
7081256Syl150051 		}
7091256Syl150051 #endif
7101256Syl150051 
7111256Syl150051 #else
7121256Syl150051 		xge_assert(rxdp->host_control!=0);
7131256Syl150051 #endif
7141256Syl150051 #endif
7151256Syl150051 
7161256Syl150051 		__hal_channel_dtr_complete(ring);
7171256Syl150051 
7183115Syl150051 		*t_code	= (u8)XGE_HAL_RXD_GET_T_CODE(rxdp->control_1);
7191256Syl150051 
7203115Syl150051 				/* see XGE_HAL_SET_RXD_T_CODE()	above..	*/
7211256Syl150051 		xge_assert(*t_code != XGE_HAL_RXD_T_CODE_UNUSED_C);
7221256Syl150051 
7231256Syl150051 		xge_debug_ring(XGE_TRACE,
724*6937Sxw161283 			"compl_index %d	post_qid %d	t_code %d rxd 0x"XGE_OS_LLXFMT,
7251256Syl150051 			((xge_hal_channel_t*)ring)->compl_index,
726*6937Sxw161283 			((xge_hal_channel_t*)ring)->post_qid, *t_code,
7271256Syl150051 			(unsigned long long)(ulong_t)rxdp);
7281256Syl150051 
7293115Syl150051 		ring->channel.usage_cnt++;
7303115Syl150051 		if (ring->channel.stats.usage_max <	ring->channel.usage_cnt)
7313115Syl150051 			ring->channel.stats.usage_max =	ring->channel.usage_cnt;
7323115Syl150051 
7331256Syl150051 		return XGE_HAL_OK;
7341256Syl150051 	}
7351256Syl150051 
7363115Syl150051 	/* reset it. since we don't	want to	return
7371256Syl150051 	 * garbage to the ULD */
7383115Syl150051 	*dtrh =	0;
7391256Syl150051 	return XGE_HAL_INF_NO_MORE_COMPLETED_DESCRIPTORS;
7401256Syl150051 }
7411256Syl150051 
7421256Syl150051 /**
7433115Syl150051  * xge_hal_ring_dtr_free - Free	descriptor.
7441256Syl150051  * @channelh: Channel handle.
7451256Syl150051  * @dtrh: Descriptor handle.
7461256Syl150051  *
7473115Syl150051  * Free	the	reserved descriptor. This operation	is "symmetrical" to
7483115Syl150051  * xge_hal_ring_dtr_reserve. The "free-ing"	completes the descriptor's
7491256Syl150051  * lifecycle.
7501256Syl150051  *
7513115Syl150051  * After free-ing (see xge_hal_ring_dtr_free())	the	descriptor again can
7521256Syl150051  * be:
7531256Syl150051  *
7541256Syl150051  * - reserved (xge_hal_ring_dtr_reserve);
7551256Syl150051  *
7563115Syl150051  * - posted	(xge_hal_ring_dtr_post);
7571256Syl150051  *
7581256Syl150051  * - completed (xge_hal_ring_dtr_next_completed);
7591256Syl150051  *
7603115Syl150051  * - and recycled again	(xge_hal_ring_dtr_free).
7611256Syl150051  *
7621256Syl150051  * For alternative state transitions and more details please refer to
7631256Syl150051  * the design doc.
7641256Syl150051  *
7651256Syl150051  * See also: xge_hal_ring_dtr_reserve(), xge_hal_fifo_dtr_free().
7661256Syl150051  * Usage: See ex_rx_compl{}.
7671256Syl150051  */
7683115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	void
xge_hal_ring_dtr_free(xge_hal_channel_h channelh,xge_hal_dtr_h dtrh)7693115Syl150051 xge_hal_ring_dtr_free(xge_hal_channel_h	channelh, xge_hal_dtr_h	dtrh)
7701256Syl150051 {
7713115Syl150051 #if	defined(XGE_HAL_RX_MULTI_FREE_IRQ)
7721256Syl150051 	unsigned long flags;
7731256Syl150051 #endif
7741256Syl150051 
7753115Syl150051 #if	defined(XGE_HAL_RX_MULTI_FREE)
7761256Syl150051 	xge_os_spin_lock(&((xge_hal_channel_t*)channelh)->free_lock);
7771256Syl150051 #elif defined(XGE_HAL_RX_MULTI_FREE_IRQ)
7781256Syl150051 	xge_os_spin_lock_irq(&((xge_hal_channel_t*)channelh)->free_lock,
7791256Syl150051 	flags);
7801256Syl150051 #endif
7811256Syl150051 
7821256Syl150051 	__hal_channel_dtr_free(channelh, dtrh);
7833115Syl150051 #if	defined(XGE_OS_MEMORY_CHECK)
784*6937Sxw161283 	__hal_ring_rxd_priv((xge_hal_ring_t * ) channelh, dtrh)->allocated = 0;
7851256Syl150051 #endif
7861256Syl150051 
7873115Syl150051 #if	defined(XGE_HAL_RX_MULTI_FREE)
7881256Syl150051 	xge_os_spin_unlock(&((xge_hal_channel_t*)channelh)->free_lock);
7891256Syl150051 #elif defined(XGE_HAL_RX_MULTI_FREE_IRQ)
7901256Syl150051 	xge_os_spin_unlock_irq(&((xge_hal_channel_t*)channelh)->free_lock,
7911256Syl150051 	flags);
7921256Syl150051 #endif
7931256Syl150051 }
7943115Syl150051 
7953115Syl150051 /**
7963115Syl150051  * xge_hal_ring_is_next_dtr_completed -	Check if the next dtr is completed
7973115Syl150051  * @channelh: Channel handle.
7983115Syl150051  *
7993115Syl150051  * Checks if the the _next_	completed descriptor is	in host	memory
8003115Syl150051  *
8013115Syl150051  * Returns:	XGE_HAL_OK - success.
8023115Syl150051  * XGE_HAL_INF_NO_MORE_COMPLETED_DESCRIPTORS - No completed	descriptors
8033115Syl150051  * are currently available for processing.
8043115Syl150051  */
8053115Syl150051 __HAL_STATIC_RING __HAL_INLINE_RING	xge_hal_status_e
xge_hal_ring_is_next_dtr_completed(xge_hal_channel_h channelh)8063115Syl150051 xge_hal_ring_is_next_dtr_completed(xge_hal_channel_h channelh)
8073115Syl150051 {
8083115Syl150051 	xge_hal_ring_rxd_1_t *rxdp;	/* doesn't matter 1, 3 or 5... */
8093115Syl150051 	xge_hal_ring_t *ring = (xge_hal_ring_t *)channelh;
8103115Syl150051 	xge_hal_dtr_h dtrh;
8113115Syl150051 
8123115Syl150051 	__hal_channel_dtr_try_complete(ring, &dtrh);
8133115Syl150051 	rxdp = (xge_hal_ring_rxd_1_t *)dtrh;
8143115Syl150051 	if (rxdp ==	NULL) {
8153115Syl150051 		return XGE_HAL_INF_NO_MORE_COMPLETED_DESCRIPTORS;
8163115Syl150051 	}
8173115Syl150051 
8183115Syl150051 	/* check whether it	is not the end */
8193115Syl150051 	if (!(rxdp->control_2 &	XGE_HAL_RXD_NOT_COMPLETED) &&
8203115Syl150051 		!(rxdp->control_1 &	XGE_HAL_RXD_POSTED_4_XFRAME)) {
8213115Syl150051 
8223115Syl150051 #ifdef XGE_DEBUG_ASSERT
8233115Syl150051 #if	defined(XGE_HAL_USE_5B_MODE)
8243115Syl150051 #if	!defined(XGE_OS_PLATFORM_64BIT)
8253115Syl150051 		if (ring->buffer_mode == XGE_HAL_RING_QUEUE_BUFFER_MODE_5) {
8263115Syl150051 			xge_assert(((xge_hal_ring_rxd_5_t *)
8273115Syl150051 					rxdp)->host_control!=0);
8283115Syl150051 		}
8293115Syl150051 #endif
8303115Syl150051 
8313115Syl150051 #else
8323115Syl150051 		xge_assert(rxdp->host_control!=0);
8333115Syl150051 #endif
8343115Syl150051 #endif
8353115Syl150051 		return XGE_HAL_OK;
8363115Syl150051 	}
8373115Syl150051 
8383115Syl150051 	return XGE_HAL_INF_NO_MORE_COMPLETED_DESCRIPTORS;
8393115Syl150051 }
840