lio_droq.h revision 325618
1/*
2 *   BSD LICENSE
3 *
4 *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
5 *   All rights reserved.
6 *
7 *   Redistribution and use in source and binary forms, with or without
8 *   modification, are permitted provided that the following conditions
9 *   are met:
10 *
11 *     * Redistributions of source code must retain the above copyright
12 *       notice, this list of conditions and the following disclaimer.
13 *     * Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in
15 *       the documentation and/or other materials provided with the
16 *       distribution.
17 *     * Neither the name of Cavium, Inc. nor the names of its
18 *       contributors may be used to endorse or promote products derived
19 *       from this software without specific prior written permission.
20 *
21 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33/*$FreeBSD: stable/11/sys/dev/liquidio/base/lio_droq.h 325618 2017-11-09 19:52:56Z sbruno $*/
34
35/*   \file  lio_droq.h
36 *   \brief Implementation of Octeon Output queues. "Output" is with
37 *   respect to the Octeon device on the NIC. From this driver's point of
38 *   view they are ingress queues.
39 */
40
41#ifndef __LIO_DROQ_H__
42#define __LIO_DROQ_H__
43
44/*
45 *  Octeon descriptor format.
46 *  The descriptor ring is made of descriptors which have 2 64-bit values:
47 *  -# Physical (bus) address of the data buffer.
48 *  -# Physical (bus) address of a lio_droq_info structure.
49 *  The Octeon device DMA's incoming packets and its information at the address
50 *  given by these descriptor fields.
51 */
52struct lio_droq_desc {
53	/* The buffer pointer */
54	uint64_t	buffer_ptr;
55
56	/* The Info pointer */
57	uint64_t	info_ptr;
58};
59
60#define LIO_DROQ_DESC_SIZE	(sizeof(struct lio_droq_desc))
61
62/*
63 *  Information about packet DMA'ed by Octeon.
64 *  The format of the information available at Info Pointer after Octeon
65 *  has posted a packet. Not all descriptors have valid information. Only
66 *  the Info field of the first descriptor for a packet has information
67 *  about the packet.
68 */
69struct lio_droq_info {
70	/* The Length of the packet. */
71	uint64_t	length;
72
73	/* The Output Receive Header. */
74	union		octeon_rh rh;
75
76};
77
78#define LIO_DROQ_INFO_SIZE	(sizeof(struct lio_droq_info))
79
80/*
81 *  Pointer to data buffer.
82 *  Driver keeps a pointer to the data buffer that it made available to
83 *  the Octeon device. Since the descriptor ring keeps physical (bus)
84 *  addresses, this field is required for the driver to keep track of
85 *  the virtual address pointers.
86 */
87struct lio_recv_buffer {
88	/* Packet buffer, including metadata. */
89	void	*buffer;
90
91	/* Data in the packet buffer.  */
92	uint8_t	*data;
93};
94
95#define LIO_DROQ_RECVBUF_SIZE	(sizeof(struct lio_recv_buffer))
96
97/* Output Queue statistics. Each output queue has four stats fields. */
98struct lio_droq_stats {
99	/* Number of packets received in this queue. */
100	uint64_t	pkts_received;
101
102	/* Bytes received by this queue. */
103	uint64_t	bytes_received;
104
105	/* Packets dropped due to no dispatch function. */
106	uint64_t	dropped_nodispatch;
107
108	/* Packets dropped due to no memory available. */
109	uint64_t	dropped_nomem;
110
111	/* Packets dropped due to large number of pkts to process. */
112	uint64_t	dropped_toomany;
113
114	/* Number of packets  sent to stack from this queue. */
115	uint64_t	rx_pkts_received;
116
117	/* Number of Bytes sent to stack from this queue. */
118	uint64_t	rx_bytes_received;
119
120	/* Num of Packets dropped due to receive path failures. */
121	uint64_t	rx_dropped;
122
123	uint64_t	rx_vxlan;
124
125	/* Num of failures of lio_recv_buffer_alloc() */
126	uint64_t	rx_alloc_failure;
127
128};
129
130/*
131 * The maximum number of buffers that can be dispatched from the
132 * output/dma queue. Set to 64 assuming 1K buffers in DROQ and the fact that
133 * max packet size from DROQ is 64K.
134 */
135#define LIO_MAX_RECV_BUFS	64
136
137/*
138 *  Receive Packet format used when dispatching output queue packets
139 *  with non-raw opcodes.
140 *  The received packet will be sent to the upper layers using this
141 *  structure which is passed as a parameter to the dispatch function
142 */
143struct lio_recv_pkt {
144	/* Number of buffers in this received packet */
145	uint16_t	buffer_count;
146
147	/* Id of the device that is sending the packet up */
148	uint16_t	octeon_id;
149
150	/* Length of data in the packet buffer */
151	uint32_t	length;
152
153	/* The receive header */
154	union octeon_rh	rh;
155
156	/* Pointer to the OS-specific packet buffer */
157	struct mbuf	*buffer_ptr[LIO_MAX_RECV_BUFS];
158
159	/* Size of the buffers pointed to by ptr's in buffer_ptr */
160	uint32_t	buffer_size[LIO_MAX_RECV_BUFS];
161};
162
163#define LIO_RECV_PKT_SIZE	(sizeof(struct lio_recv_pkt))
164
165/*
166 *  The first parameter of a dispatch function.
167 *  For a raw mode opcode, the driver dispatches with the device
168 *  pointer in this structure.
169 *  For non-raw mode opcode, the driver dispatches the recv_pkt
170 *  created to contain the buffers with data received from Octeon.
171 *  ---------------------
172 *  |     *recv_pkt ----|---
173 *  |-------------------|   |
174 *  | 0 or more bytes   |   |
175 *  | reserved by driver|   |
176 *  |-------------------|<-/
177 *  | lio_recv_pkt   |
178 *  |                   |
179 *  |___________________|
180 */
181struct lio_recv_info {
182	void			*rsvd;
183	struct lio_recv_pkt	*recv_pkt;
184};
185
186#define LIO_RECV_INFO_SIZE	(sizeof(struct lio_recv_info))
187
188/*
189 *  Allocate a recv_info structure. The recv_pkt pointer in the recv_info
190 *  structure is filled in before this call returns.
191 *  @param extra_bytes - extra bytes to be allocated at the end of the recv info
192 *                       structure.
193 *  @return - pointer to a newly allocated recv_info structure.
194 */
195static inline struct lio_recv_info *
196lio_alloc_recv_info(int extra_bytes)
197{
198	struct lio_recv_info	*recv_info;
199	uint8_t			*buf;
200
201	buf = malloc(LIO_RECV_PKT_SIZE + LIO_RECV_INFO_SIZE +
202		     extra_bytes, M_DEVBUF, M_NOWAIT | M_ZERO);
203	if (buf == NULL)
204		return (NULL);
205
206	recv_info = (struct lio_recv_info *)buf;
207	recv_info->recv_pkt = (struct lio_recv_pkt *)(buf + LIO_RECV_INFO_SIZE);
208	recv_info->rsvd = NULL;
209	if (extra_bytes)
210		recv_info->rsvd = buf + LIO_RECV_INFO_SIZE + LIO_RECV_PKT_SIZE;
211
212	return (recv_info);
213}
214
215/*
216 *  Free a recv_info structure.
217 *  @param recv_info - Pointer to receive_info to be freed
218 */
219static inline void
220lio_free_recv_info(struct lio_recv_info *recv_info)
221{
222
223	free(recv_info, M_DEVBUF);
224}
225
226typedef int	(*lio_dispatch_fn_t)(struct lio_recv_info *, void *);
227
228/*
229 * Used by NIC module to register packet handler and to get device
230 * information for each octeon device.
231 */
232struct lio_droq_ops {
233	/*
234	 *  This registered function will be called by the driver with
235	 *  the pointer to buffer from droq and length of
236	 *  data in the buffer. The receive header gives the port
237	 *  number to the caller.  Function pointer is set by caller.
238	 */
239	void		(*fptr) (void *, uint32_t, union octeon_rh *, void  *,
240				 void *);
241	void		*farg;
242
243	/*
244	 *  Flag indicating if the DROQ handler should drop packets that
245	 *  it cannot handle in one iteration. Set by caller.
246	 */
247	uint32_t	drop_on_max;
248};
249
250/*
251 * The Descriptor Ring Output Queue structure.
252 *  This structure has all the information required to implement a
253 *  Octeon DROQ.
254 */
255struct lio_droq {
256	/* A lock to protect access to this ring. */
257	struct mtx		lock;
258
259	uint32_t		q_no;
260
261	uint32_t		pkt_count;
262
263	struct lio_droq_ops	ops;
264
265	struct octeon_device	*oct_dev;
266
267	/* The 8B aligned descriptor ring starts at this address. */
268	struct lio_droq_desc	*desc_ring;
269
270	/* Index in the ring where the driver should read the next packet */
271	uint32_t		read_idx;
272
273	/*
274	 * Index in the ring where the driver will refill the descriptor's
275	 * buffer
276	 */
277	uint32_t		refill_idx;
278
279	/* Packets pending to be processed */
280	volatile int		pkts_pending;
281
282	/* Number of  descriptors in this ring. */
283	uint32_t		max_count;
284
285	/* The number of descriptors pending refill. */
286	uint32_t		refill_count;
287
288	uint32_t		pkts_per_intr;
289	uint32_t		refill_threshold;
290
291	/*
292	 * The max number of descriptors in DROQ without a buffer.
293	 * This field is used to keep track of empty space threshold. If the
294	 * refill_count reaches this value, the DROQ cannot accept a max-sized
295	 * (64K) packet.
296	 */
297	uint32_t		max_empty_descs;
298
299	/*
300	 * The receive buffer list. This list has the virtual addresses of
301	 * the buffers.
302	 */
303	struct lio_recv_buffer	*recv_buf_list;
304
305	/* The size of each buffer pointed by the buffer pointer. */
306	uint32_t		buffer_size;
307
308	/*
309	 * Offset to packet credit register.
310	 * Host writes number of info/buffer ptrs available to this register
311	 */
312	uint32_t		pkts_credit_reg;
313
314	/*
315	 * Offset packet sent register.
316	 * Octeon writes the number of packets DMA'ed to host memory
317	 * in this register.
318	 */
319	uint32_t		pkts_sent_reg;
320
321	struct lio_stailq_head	dispatch_stq_head;
322
323	/* Statistics for this DROQ. */
324	struct lio_droq_stats	stats;
325
326	/* DMA mapped address of the DROQ descriptor ring. */
327	vm_paddr_t		desc_ring_dma;
328
329	/* application context */
330	void			*app_ctx;
331
332	uint32_t		cpu_id;
333
334	struct task		droq_task;
335	struct taskqueue	*droq_taskqueue;
336
337	struct lro_ctrl		lro;
338};
339
340#define LIO_DROQ_SIZE	(sizeof(struct lio_droq))
341
342/*
343 * Allocates space for the descriptor ring for the droq and sets the
344 *   base addr, num desc etc in Octeon registers.
345 *
346 * @param  oct_dev    - pointer to the octeon device structure
347 * @param  q_no       - droq no.
348 * @param app_ctx     - pointer to application context
349 * @return Success: 0    Failure: 1
350 */
351int	lio_init_droq(struct octeon_device *oct_dev,
352		      uint32_t q_no, uint32_t num_descs, uint32_t desc_size,
353		      void *app_ctx);
354
355/*
356 *  Frees the space for descriptor ring for the droq.
357 *
358 *  @param oct_dev - pointer to the octeon device structure
359 *  @param q_no    - droq no.
360 *  @return:    Success: 0    Failure: 1
361 */
362int	lio_delete_droq(struct octeon_device *oct_dev, uint32_t q_no);
363
364/*
365 * Register a change in droq operations. The ops field has a pointer to a
366 * function which will called by the DROQ handler for all packets arriving
367 * on output queues given by q_no irrespective of the type of packet.
368 * The ops field also has a flag which if set tells the DROQ handler to
369 * drop packets if it receives more than what it can process in one
370 * invocation of the handler.
371 * @param oct       - octeon device
372 * @param q_no      - octeon output queue number (0 <= q_no <= MAX_OCTEON_DROQ-1
373 * @param ops       - the droq_ops settings for this queue
374 * @return          - 0 on success, -ENODEV or -EINVAL on error.
375 */
376int	lio_register_droq_ops(struct octeon_device *oct, uint32_t q_no,
377			      struct lio_droq_ops *ops);
378
379/*
380 * Resets the function pointer and flag settings made by
381 * lio_register_droq_ops(). After this routine is called, the DROQ handler
382 * will lookup dispatch function for each arriving packet on the output queue
383 * given by q_no.
384 * @param oct       - octeon device
385 * @param q_no      - octeon output queue number (0 <= q_no <= MAX_OCTEON_DROQ-1
386 * @return          - 0 on success, -ENODEV or -EINVAL on error.
387 */
388int	lio_unregister_droq_ops(struct octeon_device *oct, uint32_t q_no);
389
390/*
391 *    Register a dispatch function for a opcode/subcode. The driver will call
392 *    this dispatch function when it receives a packet with the given
393 *    opcode/subcode in its output queues along with the user specified
394 *    argument.
395 *    @param  oct        - the octeon device to register with.
396 *    @param  opcode     - the opcode for which the dispatch will be registered.
397 *    @param  subcode    - the subcode for which the dispatch will be registered
398 *    @param  fn         - the dispatch function.
399 *    @param  fn_arg     - user specified that will be passed along with the
400 *                         dispatch function by the driver.
401 *    @return Success: 0; Failure: 1
402 */
403int	lio_register_dispatch_fn(struct octeon_device *oct, uint16_t opcode,
404				 uint16_t subcode, lio_dispatch_fn_t fn,
405				 void *fn_arg);
406
407/*
408 *   Remove registration for an opcode/subcode. This will delete the mapping for
409 *   an opcode/subcode. The dispatch function will be unregistered and will no
410 *   longer be called if a packet with the opcode/subcode arrives in the driver
411 *   output queues.
412 *   @param  oct        -  the octeon device to unregister from.
413 *   @param  opcode     -  the opcode to be unregistered.
414 *   @param  subcode    -  the subcode to be unregistered.
415 *
416 *   @return Success: 0; Failure: 1
417 */
418int	lio_unregister_dispatch_fn(struct octeon_device *oct, uint16_t opcode,
419				   uint16_t subcode);
420
421uint32_t	lio_droq_check_hw_for_pkts(struct lio_droq *droq);
422
423int	lio_create_droq(struct octeon_device *oct, uint32_t q_no,
424			uint32_t num_descs, uint32_t desc_size, void *app_ctx);
425
426int	lio_droq_process_packets(struct octeon_device *oct,
427				 struct lio_droq *droq, uint32_t budget);
428
429uint32_t	lio_droq_refill(struct octeon_device *octeon_dev,
430				struct lio_droq *droq);
431void	lio_droq_bh(void *ptr, int pending __unused);
432#endif	/* __LIO_DROQ_H__ */
433