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