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