1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Copyright (c) 2002-2006 Neterion, Inc.
22 */
23
24#ifndef XGE_HAL_FIFO_H
25#define XGE_HAL_FIFO_H
26
27#include "xgehal-channel.h"
28#include "xgehal-config.h"
29#include "xgehal-mm.h"
30
31__EXTERN_BEGIN_DECLS
32
33/* HW fifo configuration */
34#define	XGE_HAL_FIFO_INT_PER_LIST_THRESHOLD	65
35#define XGE_HAL_FIFO_MAX_WRR			5
36#define XGE_HAL_FIFO_MAX_PARTITION		4
37#define XGE_HAL_FIFO_MAX_WRR_STATE		36
38#define XGE_HAL_FIFO_HW_PAIR_OFFSET		0x20000
39
40/* HW FIFO Weight Calender */
41#define XGE_HAL_FIFO_WRR_0      0x0706050407030602ULL
42#define XGE_HAL_FIFO_WRR_1      0x0507040601070503ULL
43#define XGE_HAL_FIFO_WRR_2      0x0604070205060700ULL
44#define XGE_HAL_FIFO_WRR_3      0x0403060705010207ULL
45#define XGE_HAL_FIFO_WRR_4      0x0604050300000000ULL
46/*
47 * xge_hal_fifo_hw_pair_t
48 *
49 * Represent a single fifo in the BAR1 memory space.
50 */
51typedef struct {
52	u64 txdl_pointer; /* offset 0x0 */
53
54	u64 reserved[2];
55
56	u64 list_control; /* offset 0x18 */
57#define XGE_HAL_TX_FIFO_LAST_TXD_NUM( val)     vBIT(val,0,8)
58#define XGE_HAL_TX_FIFO_FIRST_LIST             BIT(14)
59#define XGE_HAL_TX_FIFO_LAST_LIST              BIT(15)
60#define XGE_HAL_TX_FIFO_FIRSTNLAST_LIST        vBIT(3,14,2)
61#define XGE_HAL_TX_FIFO_SPECIAL_FUNC           BIT(23)
62#define XGE_HAL_TX_FIFO_NO_SNOOP(n)            vBIT(n,30,2)
63} xge_hal_fifo_hw_pair_t;
64
65
66/* Bad TxDL transfer codes */
67#define XGE_HAL_TXD_T_CODE_OK		        0x0
68#define XGE_HAL_TXD_T_CODE_UNUSED_1		0x1
69#define XGE_HAL_TXD_T_CODE_ABORT_BUFFER		0x2
70#define XGE_HAL_TXD_T_CODE_ABORT_DTOR		0x3
71#define XGE_HAL_TXD_T_CODE_UNUSED_5		0x5
72#define XGE_HAL_TXD_T_CODE_PARITY		0x7
73#define XGE_HAL_TXD_T_CODE_LOSS_OF_LINK		0xA
74#define XGE_HAL_TXD_T_CODE_GENERAL_ERR		0xF
75
76
77/**
78 * struct xge_hal_fifo_txd_t - TxD.
79 * @control_1: Control_1.
80 * @control_2: Control_2.
81 * @buffer_pointer: Buffer_Address.
82 * @host_control: Host_Control.Opaque 64bit data stored by ULD inside the Xframe
83 *            descriptor prior to posting the latter on the channel
84 *            via xge_hal_fifo_dtr_post() or xge_hal_ring_dtr_post().
85 *            The %host_control is returned as is to the ULD with each
86 *            completed descriptor.
87 *
88 * Transmit descriptor (TxD).Fifo descriptor contains configured number
89 * (list) of TxDs. * For more details please refer to Xframe User Guide,
90 * Section 5.4.2 "Transmit Descriptor (TxD) Format".
91 */
92typedef struct xge_hal_fifo_txd_t {
93	u64 control_1;
94#define XGE_HAL_TXD_LIST_OWN_XENA       BIT(7)
95#define XGE_HAL_TXD_T_CODE		(BIT(12)|BIT(13)|BIT(14)|BIT(15))
96#define XGE_HAL_GET_TXD_T_CODE(val)     ((val & XGE_HAL_TXD_T_CODE)>>48)
97#define XGE_HAL_SET_TXD_T_CODE(x, val)  (x |= (((u64)val & 0xF) << 48))
98#define XGE_HAL_TXD_GATHER_CODE         (BIT(22) | BIT(23))
99#define XGE_HAL_TXD_GATHER_CODE_FIRST   BIT(22)
100#define XGE_HAL_TXD_GATHER_CODE_LAST    BIT(23)
101#define XGE_HAL_TXD_NO_LSO				0
102#define XGE_HAL_TXD_UDF_COF				1
103#define XGE_HAL_TXD_TCP_LSO				2
104#define XGE_HAL_TXD_UDP_LSO				3
105#define XGE_HAL_TXD_LSO_COF_CTRL(val)   vBIT(val,30,2)
106#define XGE_HAL_TXD_TCP_LSO_MSS(val)    vBIT(val,34,14)
107#define XGE_HAL_TXD_BUFFER0_SIZE(val)   vBIT(val,48,16)
108#define XGE_HAL_TXD_GET_LSO_BYTES_SENT(val) ((val & vBIT(0xFFFF,16,16))>>32)
109	u64 control_2;
110#define XGE_HAL_TXD_TX_CKO_CONTROL      (BIT(5)|BIT(6)|BIT(7))
111#define XGE_HAL_TXD_TX_CKO_IPV4_EN      BIT(5)
112#define XGE_HAL_TXD_TX_CKO_TCP_EN       BIT(6)
113#define XGE_HAL_TXD_TX_CKO_UDP_EN       BIT(7)
114#define XGE_HAL_TXD_VLAN_ENABLE         BIT(15)
115#define XGE_HAL_TXD_VLAN_TAG(val)       vBIT(val,16,16)
116#define XGE_HAL_TXD_INT_NUMBER(val)     vBIT(val,34,6)
117#define XGE_HAL_TXD_INT_TYPE_PER_LIST   BIT(47)
118#define XGE_HAL_TXD_INT_TYPE_UTILZ      BIT(46)
119#define XGE_HAL_TXD_SET_MARKER          vBIT(0x6,0,4)
120
121	u64 buffer_pointer;
122
123	u64 host_control;
124
125} xge_hal_fifo_txd_t;
126
127typedef xge_hal_fifo_txd_t* xge_hal_fifo_txdl_t;
128
129/**
130 * struct xge_hal_fifo_t - Fifo channel.
131 * @channel: Channel "base" of this fifo, the common part of all HAL
132 *           channels.
133 * @post_lock_ptr: Points to a lock that serializes (pointer, control) PIOs.
134 *           Note that for Xena the serialization is done across all device
135 *           fifos.
136 * @hw_pair: Per-fifo (Pointer, Control) pair used to send descriptors to the
137 *           Xframe hardware (for details see Xframe user guide).
138 * @config: Fifo configuration, part of device configuration
139 *          (see xge_hal_device_config_t{}).
140 * @no_snoop_bits: See xge_hal_fifo_config_t{}.
141 * @txdl_per_memblock: Number of TxDLs (TxD lists) per memblock.
142 * on TxDL please refer to Xframe UG.
143 * @interrupt_type: FIXME: to-be-defined.
144 * @txdl_size: Configured TxDL size (i.e., number of TxDs in a list), plus
145 *             per-TxDL HAL private space (xge_hal_fifo_txdl_priv_t).
146 * @priv_size: Per-Tx descriptor space reserved for upper-layer driver
147 *             usage.
148 * @mempool: Memory pool, from which descriptors get allocated.
149 * @align_size: TBD
150 *
151 * Fifo channel.
152 * Note: The structure is cache line aligned.
153 */
154typedef struct xge_hal_fifo_t {
155	xge_hal_channel_t	channel;
156	spinlock_t		*post_lock_ptr;
157	xge_hal_fifo_hw_pair_t	*hw_pair;
158	xge_hal_fifo_config_t	*config;
159	int			no_snoop_bits;
160	int			txdl_per_memblock;
161	u64			interrupt_type;
162	int			txdl_size;
163	int			priv_size;
164	xge_hal_mempool_t	*mempool;
165	int			align_size;
166} __xge_os_attr_cacheline_aligned xge_hal_fifo_t;
167
168/**
169 * struct xge_hal_fifo_txdl_priv_t - Transmit descriptor HAL-private
170 * data.
171 * @dma_addr: DMA (mapped) address of _this_ descriptor.
172 * @dma_handle: DMA handle used to map the descriptor onto device.
173 * @dma_offset: Descriptor's offset in the memory block. HAL allocates
174 * descriptors in memory blocks (see
175 * xge_hal_fifo_config_t{})
176 * Each memblock is a contiguous block of DMA-able memory.
177 * @frags: Total number of fragments (that is, contiguous data buffers)
178 * carried by this TxDL.
179 * @align_vaddr_start: (TODO).
180 * @align_vaddr: Virtual address of the per-TxDL area in memory used for
181 * alignement. Used to place one or more mis-aligned fragments
182 * (the maximum defined by configration variable
183 * @max_aligned_frags).
184 * @align_dma_addr: DMA address translated from the @align_vaddr.
185 * @align_dma_handle: DMA handle that corresponds to @align_dma_addr.
186 * @align_dma_acch: DMA access handle corresponds to @align_dma_addr.
187 * @align_dma_offset: The current offset into the @align_vaddr area.
188 * Grows while filling the descriptor, gets reset.
189 * @align_used_frags: (TODO).
190 * @alloc_frags: Total number of fragments allocated.
191 * @dang_frags: Number of fragments kept from release until this TxDL is freed.
192 * @bytes_sent: TODO
193 * @unused: TODO
194 * @dang_txdl: (TODO).
195 * @next_txdl_priv: (TODO).
196 * @first_txdp: (TODO).
197 * @dang_dtrh: Pointer to TxDL (list) kept from release until this TxDL
198 * is freed.
199 * @linked_txdl_priv: Pointer to any linked TxDL for creating contiguous
200 * TxDL list.
201 * @dtrh: Corresponding dtrh to this TxDL.
202 * @memblock: Pointer to the TxDL memory block or memory page.
203 * on the next send operation.
204 * @dma_object: DMA address and handle of the memory block that contains
205 * the descriptor. This member is used only in the "checked"
206 * version of the HAL (to enforce certain assertions);
207 * otherwise it gets compiled out.
208 * @allocated: True if the descriptor is reserved, 0 otherwise. Internal usage.
209 *
210 * Per-transmit decsriptor HAL-private data. HAL uses the space to keep DMA
211 * information associated with the descriptor. Note that ULD can ask HAL
212 * to allocate additional per-descriptor space for its own (ULD-specific)
213 * purposes.
214 *
215 * See also: xge_hal_ring_rxd_priv_t{}.
216 */
217typedef struct xge_hal_fifo_txdl_priv_t {
218	dma_addr_t				dma_addr;
219	pci_dma_h				dma_handle;
220	ptrdiff_t				dma_offset;
221	int					frags;
222	char					*align_vaddr_start;
223	char					*align_vaddr;
224	dma_addr_t				align_dma_addr;
225	pci_dma_h				align_dma_handle;
226	pci_dma_acc_h				align_dma_acch;
227	ptrdiff_t				align_dma_offset;
228	int					align_used_frags;
229	int					alloc_frags;
230	int					dang_frags;
231	unsigned int				bytes_sent;
232	int					unused;
233	xge_hal_fifo_txd_t			*dang_txdl;
234	struct xge_hal_fifo_txdl_priv_t		*next_txdl_priv;
235	xge_hal_fifo_txd_t			*first_txdp;
236	void					*memblock;
237#ifdef XGE_DEBUG_ASSERT
238	xge_hal_mempool_dma_t			*dma_object;
239#endif
240#ifdef XGE_OS_MEMORY_CHECK
241	int					allocated;
242#endif
243} xge_hal_fifo_txdl_priv_t;
244
245/**
246 * xge_hal_fifo_get_max_frags_cnt - Return the max fragments allocated
247 * for the fifo.
248 * @channelh: Channel handle.
249 */
250static inline int
251xge_hal_fifo_get_max_frags_cnt(xge_hal_channel_h channelh)
252{
253	return ((xge_hal_fifo_t *)channelh)->config->max_frags;
254}
255/* ========================= FIFO PRIVATE API ============================= */
256
257xge_hal_status_e __hal_fifo_open(xge_hal_channel_h channelh,
258			xge_hal_channel_attr_t *attr);
259
260void __hal_fifo_close(xge_hal_channel_h channelh);
261
262void __hal_fifo_hw_initialize(xge_hal_device_h hldev);
263
264xge_hal_status_e
265__hal_fifo_dtr_align_alloc_map(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh);
266
267void
268__hal_fifo_dtr_align_free_unmap(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh);
269
270#if defined(XGE_DEBUG_FP) && (XGE_DEBUG_FP & XGE_DEBUG_FP_FIFO)
271#define __HAL_STATIC_FIFO
272#define __HAL_INLINE_FIFO
273
274__HAL_STATIC_FIFO __HAL_INLINE_FIFO xge_hal_fifo_txdl_priv_t*
275__hal_fifo_txdl_priv(xge_hal_dtr_h dtrh);
276
277__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
278__hal_fifo_dtr_post_single(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh,
279			u64 ctrl_1);
280__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
281__hal_fifo_txdl_restore_many(xge_hal_channel_h channelh,
282			  xge_hal_fifo_txd_t *txdp, int txdl_count);
283
284/* ========================= FIFO PUBLIC API ============================== */
285
286__HAL_STATIC_FIFO __HAL_INLINE_FIFO xge_hal_status_e
287xge_hal_fifo_dtr_reserve(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh);
288
289__HAL_STATIC_FIFO __HAL_INLINE_FIFO xge_hal_status_e
290xge_hal_fifo_dtr_reserve_many(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh,
291    const int frags);
292
293__HAL_STATIC_FIFO __HAL_INLINE_FIFO void*
294xge_hal_fifo_dtr_private(xge_hal_dtr_h dtrh);
295
296__HAL_STATIC_FIFO __HAL_INLINE_FIFO int
297xge_hal_fifo_dtr_buffer_cnt(xge_hal_dtr_h dtrh);
298
299__HAL_STATIC_FIFO __HAL_INLINE_FIFO xge_hal_status_e
300xge_hal_fifo_dtr_reserve_sp(xge_hal_channel_h channel, int dtr_sp_size,
301			xge_hal_dtr_h dtr_sp);
302
303__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
304xge_hal_fifo_dtr_post(xge_hal_channel_h	channelh, xge_hal_dtr_h dtrh);
305
306__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
307xge_hal_fifo_dtr_post_many(xge_hal_channel_h channelh, int num,
308			xge_hal_dtr_h dtrs[]);
309
310__HAL_STATIC_FIFO __HAL_INLINE_FIFO xge_hal_status_e
311xge_hal_fifo_dtr_next_completed(xge_hal_channel_h channelh, xge_hal_dtr_h *dtrh,
312			u8 *t_code);
313
314__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
315xge_hal_fifo_dtr_free(xge_hal_channel_h	channelh, xge_hal_dtr_h dtr);
316
317__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
318xge_hal_fifo_dtr_buffer_set(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh,
319			int frag_idx, dma_addr_t dma_pointer, int size);
320
321__HAL_STATIC_FIFO __HAL_INLINE_FIFO xge_hal_status_e
322xge_hal_fifo_dtr_buffer_set_aligned(xge_hal_channel_h channelh,
323			xge_hal_dtr_h dtrh, int frag_idx, void *vaddr,
324			dma_addr_t dma_pointer, int size, int misaligned_size);
325
326__HAL_STATIC_FIFO __HAL_INLINE_FIFO xge_hal_status_e
327xge_hal_fifo_dtr_buffer_append(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh,
328		void *vaddr, int size);
329
330__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
331xge_hal_fifo_dtr_buffer_finalize(xge_hal_channel_h channelh, xge_hal_dtr_h dtrh,
332		int frag_idx);
333
334__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
335xge_hal_fifo_dtr_mss_set(xge_hal_dtr_h dtrh, int mss);
336
337__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
338xge_hal_fifo_dtr_cksum_set_bits(xge_hal_dtr_h dtrh, u64 cksum_bits);
339
340__HAL_STATIC_FIFO __HAL_INLINE_FIFO void
341xge_hal_fifo_dtr_vlan_set(xge_hal_dtr_h	dtrh, u16 vlan_tag);
342
343__HAL_STATIC_FIFO __HAL_INLINE_FIFO xge_hal_status_e
344xge_hal_fifo_is_next_dtr_completed(xge_hal_channel_h channelh);
345
346#else /* XGE_FASTPATH_EXTERN */
347#define __HAL_STATIC_FIFO static
348#define __HAL_INLINE_FIFO inline
349#include "xgehal-fifo-fp.c"
350#endif /* XGE_FASTPATH_INLINE */
351
352__EXTERN_END_DECLS
353
354#endif /* XGE_HAL_FIFO_H */
355