1325618Ssbruno/*
2325618Ssbruno *   BSD LICENSE
3325618Ssbruno *
4325618Ssbruno *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
5325618Ssbruno *   All rights reserved.
6325618Ssbruno *
7325618Ssbruno *   Redistribution and use in source and binary forms, with or without
8325618Ssbruno *   modification, are permitted provided that the following conditions
9325618Ssbruno *   are met:
10325618Ssbruno *
11325618Ssbruno *     * Redistributions of source code must retain the above copyright
12325618Ssbruno *       notice, this list of conditions and the following disclaimer.
13325618Ssbruno *     * Redistributions in binary form must reproduce the above copyright
14325618Ssbruno *       notice, this list of conditions and the following disclaimer in
15325618Ssbruno *       the documentation and/or other materials provided with the
16325618Ssbruno *       distribution.
17325618Ssbruno *     * Neither the name of Cavium, Inc. nor the names of its
18325618Ssbruno *       contributors may be used to endorse or promote products derived
19325618Ssbruno *       from this software without specific prior written permission.
20325618Ssbruno *
21325618Ssbruno *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22325618Ssbruno *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23325618Ssbruno *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24325618Ssbruno *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25325618Ssbruno *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26325618Ssbruno *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27325618Ssbruno *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28325618Ssbruno *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29325618Ssbruno *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30325618Ssbruno *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31325618Ssbruno *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32325618Ssbruno */
33325618Ssbruno/*$FreeBSD: stable/11/sys/dev/liquidio/base/lio_iq.h 325618 2017-11-09 19:52:56Z sbruno $*/
34325618Ssbruno
35325618Ssbruno/*   \file  lio_iq.h
36325618Ssbruno *   \brief Host Driver: Implementation of Octeon input queues. "Input" is
37325618Ssbruno *   with respect to the Octeon device on the NIC. From this driver's
38325618Ssbruno *   point of view they are egress queues.
39325618Ssbruno */
40325618Ssbruno
41325618Ssbruno#ifndef __LIO_IQ_H__
42325618Ssbruno#define __LIO_IQ_H__
43325618Ssbruno
44325618Ssbruno#define LIO_IQ_SEND_OK          0
45325618Ssbruno#define LIO_IQ_SEND_STOP        1
46325618Ssbruno#define LIO_IQ_SEND_FAILED     -1
47325618Ssbruno
48325618Ssbruno/*-------------------------  INSTRUCTION QUEUE --------------------------*/
49325618Ssbruno
50325618Ssbruno#define LIO_REQTYPE_NONE                 0
51325618Ssbruno#define LIO_REQTYPE_NORESP_NET           1
52325618Ssbruno#define LIO_REQTYPE_NORESP_NET_SG        2
53325618Ssbruno#define LIO_REQTYPE_RESP_NET             3
54325618Ssbruno#define LIO_REQTYPE_SOFT_COMMAND         4
55325618Ssbruno
56325618Ssbruno/*
57325618Ssbruno * This structure is used by NIC driver to store information required
58325618Ssbruno * to free the mbuf when the packet has been fetched by Octeon.
59325618Ssbruno * Bytes offset below assume worst-case of a 64-bit system.
60325618Ssbruno */
61325618Ssbrunostruct lio_mbuf_free_info {
62325618Ssbruno	/* Pointer to mbuf. */
63325618Ssbruno	struct mbuf		*mb;
64325618Ssbruno
65325618Ssbruno	/* Pointer to gather list. */
66325618Ssbruno	struct lio_gather	*g;
67325618Ssbruno
68325618Ssbruno	bus_dmamap_t		map;
69325618Ssbruno};
70325618Ssbruno
71325618Ssbrunostruct lio_request_list {
72325618Ssbruno	uint32_t			reqtype;
73325618Ssbruno	void				*buf;
74325618Ssbruno	bus_dmamap_t			map;
75325618Ssbruno	struct lio_mbuf_free_info	finfo;
76325618Ssbruno};
77325618Ssbruno
78325618Ssbruno/* Input Queue statistics. Each input queue has four stats fields. */
79325618Ssbrunostruct lio_iq_stats {
80325618Ssbruno	uint64_t	instr_posted;		/**< Instructions posted to this queue. */
81325618Ssbruno	uint64_t	instr_processed;	/**< Instructions processed in this queue. */
82325618Ssbruno	uint64_t	instr_dropped;		/**< Instructions that could not be processed */
83325618Ssbruno	uint64_t	bytes_sent;		/**< Bytes sent through this queue. */
84325618Ssbruno	uint64_t	sgentry_sent;		/**< Gather entries sent through this queue. */
85325618Ssbruno	uint64_t	tx_done;		/**< Num of packets sent to network. */
86325618Ssbruno	uint64_t	tx_iq_busy;		/**< Numof times this iq was found to be full. */
87325618Ssbruno	uint64_t	tx_dropped;		/**< Numof pkts dropped dueto xmitpath errors. */
88325618Ssbruno	uint64_t	tx_tot_bytes;		/**< Total count of bytes sento to network. */
89325618Ssbruno	uint64_t	tx_gso;			/* count of tso */
90325618Ssbruno	uint64_t	tx_vxlan;		/* tunnel */
91325618Ssbruno	uint64_t	tx_dmamap_fail;
92325618Ssbruno	uint64_t	tx_restart;
93325618Ssbruno	uint64_t	mbuf_defrag_failed;
94325618Ssbruno};
95325618Ssbruno
96325618Ssbruno/*
97325618Ssbruno *  The instruction (input) queue.
98325618Ssbruno *  The input queue is used to post raw (instruction) mode data or packet
99325618Ssbruno *  data to Octeon device from the host. Each input queue for
100325618Ssbruno *  a Octeon device has one such structure to represent it.
101325618Ssbruno */
102325618Ssbrunostruct lio_instr_queue {
103325618Ssbruno	struct octeon_device	*oct_dev;
104325618Ssbruno
105325618Ssbruno	/* A lock to protect access to the input ring.  */
106325618Ssbruno	struct mtx		lock;
107325618Ssbruno
108325618Ssbruno	/* A lock to protect while enqueue to the input ring.  */
109325618Ssbruno	struct mtx		enq_lock;
110325618Ssbruno
111325618Ssbruno	/* A lock to protect while posting on the ring.  */
112325618Ssbruno	struct mtx		post_lock;
113325618Ssbruno
114325618Ssbruno	uint32_t		pkt_in_done;
115325618Ssbruno
116325618Ssbruno	/* A lock to protect access to the input ring. */
117325618Ssbruno	struct mtx		iq_flush_running_lock;
118325618Ssbruno
119325618Ssbruno	/* Flag that indicates if the queue uses 64 byte commands. */
120325618Ssbruno	uint32_t		iqcmd_64B:1;
121325618Ssbruno
122325618Ssbruno	/* Queue info. */
123325618Ssbruno	union octeon_txpciq	txpciq;
124325618Ssbruno
125325618Ssbruno	uint32_t		rsvd:17;
126325618Ssbruno
127325618Ssbruno	uint32_t		status:8;
128325618Ssbruno
129325618Ssbruno	/* Maximum no. of instructions in this queue. */
130325618Ssbruno	uint32_t		max_count;
131325618Ssbruno
132325618Ssbruno	/* Index in input ring where the driver should write the next packet */
133325618Ssbruno	uint32_t		host_write_index;
134325618Ssbruno
135325618Ssbruno	/*
136325618Ssbruno	 * Index in input ring where Octeon is expected to read the next
137325618Ssbruno	 * packet.
138325618Ssbruno	 */
139325618Ssbruno	uint32_t		octeon_read_index;
140325618Ssbruno
141325618Ssbruno	/*
142325618Ssbruno	 * This index aids in finding the window in the queue where Octeon
143325618Ssbruno	 * has read the commands.
144325618Ssbruno	 */
145325618Ssbruno	uint32_t		flush_index;
146325618Ssbruno
147325618Ssbruno	/* This field keeps track of the instructions pending in this queue. */
148325618Ssbruno	volatile int		instr_pending;
149325618Ssbruno
150325618Ssbruno	uint32_t		reset_instr_cnt;
151325618Ssbruno
152325618Ssbruno	/* Pointer to the Virtual Base addr of the input ring. */
153325618Ssbruno	uint8_t			*base_addr;
154325618Ssbruno	bus_dma_tag_t		txtag;
155325618Ssbruno
156325618Ssbruno	struct lio_request_list	*request_list;
157325618Ssbruno
158325618Ssbruno	struct buf_ring		*br;
159325618Ssbruno
160325618Ssbruno	/* Octeon doorbell register for the ring. */
161325618Ssbruno	uint32_t		doorbell_reg;
162325618Ssbruno
163325618Ssbruno	/* Octeon instruction count register for this ring. */
164325618Ssbruno	uint32_t		inst_cnt_reg;
165325618Ssbruno
166325618Ssbruno	/* Number of instructions pending to be posted to Octeon. */
167325618Ssbruno	uint32_t		fill_cnt;
168325618Ssbruno
169325618Ssbruno	/* The last time that the doorbell was rung. */
170325618Ssbruno	uint64_t		last_db_time;
171325618Ssbruno
172325618Ssbruno	/*
173325618Ssbruno	 * The doorbell timeout. If the doorbell was not rung for this time
174325618Ssbruno	 * and fill_cnt is non-zero, ring the doorbell again.
175325618Ssbruno	 */
176325618Ssbruno	uint32_t		db_timeout;
177325618Ssbruno
178325618Ssbruno	/* Statistics for this input queue. */
179325618Ssbruno	struct lio_iq_stats	stats;
180325618Ssbruno
181325618Ssbruno	/* DMA mapped base address of the input descriptor ring. */
182325618Ssbruno	uint64_t		base_addr_dma;
183325618Ssbruno
184325618Ssbruno	/* Application context */
185325618Ssbruno	void			*app_ctx;
186325618Ssbruno
187325618Ssbruno	/* network stack queue index */
188325618Ssbruno	int			q_index;
189325618Ssbruno
190325618Ssbruno	/* os ifidx associated with this queue */
191325618Ssbruno	int			ifidx;
192325618Ssbruno
193325618Ssbruno};
194325618Ssbruno
195325618Ssbruno/*----------------------  INSTRUCTION FORMAT ----------------------------*/
196325618Ssbruno
197325618Ssbrunostruct lio_instr3_64B {
198325618Ssbruno	/* Pointer where the input data is available. */
199325618Ssbruno	uint64_t	dptr;
200325618Ssbruno
201325618Ssbruno	/* Instruction Header. */
202325618Ssbruno	uint64_t	ih3;
203325618Ssbruno
204325618Ssbruno	/* Instruction Header. */
205325618Ssbruno	uint64_t	pki_ih3;
206325618Ssbruno
207325618Ssbruno	/* Input Request Header. */
208325618Ssbruno	uint64_t	irh;
209325618Ssbruno
210325618Ssbruno	/* opcode/subcode specific parameters */
211325618Ssbruno	uint64_t	ossp[2];
212325618Ssbruno
213325618Ssbruno	/* Return Data Parameters */
214325618Ssbruno	uint64_t	rdp;
215325618Ssbruno
216325618Ssbruno	/*
217325618Ssbruno	 * Pointer where the response for a RAW mode packet will be written
218325618Ssbruno	 * by Octeon.
219325618Ssbruno	 */
220325618Ssbruno	uint64_t	rptr;
221325618Ssbruno
222325618Ssbruno};
223325618Ssbruno
224325618Ssbrunounion lio_instr_64B {
225325618Ssbruno	struct lio_instr3_64B	cmd3;
226325618Ssbruno};
227325618Ssbruno
228325618Ssbruno/* The size of each buffer in soft command buffer pool */
229325618Ssbruno#define LIO_SOFT_COMMAND_BUFFER_SIZE	2048
230325618Ssbruno
231325618Ssbrunostruct lio_soft_command {
232325618Ssbruno	/* Soft command buffer info. */
233325618Ssbruno	struct lio_stailq_node	node;
234325618Ssbruno	uint64_t		dma_addr;
235325618Ssbruno	uint32_t		size;
236325618Ssbruno
237325618Ssbruno	/* Command and return status */
238325618Ssbruno	union lio_instr_64B	cmd;
239325618Ssbruno
240325618Ssbruno#define COMPLETION_WORD_INIT    0xffffffffffffffffULL
241325618Ssbruno	uint64_t		*status_word;
242325618Ssbruno
243325618Ssbruno	/* Data buffer info */
244325618Ssbruno	void			*virtdptr;
245325618Ssbruno	uint64_t		dmadptr;
246325618Ssbruno	uint32_t		datasize;
247325618Ssbruno
248325618Ssbruno	/* Return buffer info */
249325618Ssbruno	void			*virtrptr;
250325618Ssbruno	uint64_t		dmarptr;
251325618Ssbruno	uint32_t		rdatasize;
252325618Ssbruno
253325618Ssbruno	/* Context buffer info */
254325618Ssbruno	void			*ctxptr;
255325618Ssbruno	uint32_t		ctxsize;
256325618Ssbruno
257325618Ssbruno	/* Time out and callback */
258325618Ssbruno	int			wait_time;
259325618Ssbruno	int			timeout;
260325618Ssbruno	uint32_t		iq_no;
261325618Ssbruno	void			(*callback) (struct octeon_device *, uint32_t,
262325618Ssbruno					     void *);
263325618Ssbruno	void			*callback_arg;
264325618Ssbruno};
265325618Ssbruno
266325618Ssbruno/* Maximum number of buffers to allocate into soft command buffer pool */
267325618Ssbruno#define LIO_MAX_SOFT_COMMAND_BUFFERS	256
268325618Ssbruno
269325618Ssbruno/* Head of a soft command buffer pool. */
270325618Ssbrunostruct lio_sc_buffer_pool {
271325618Ssbruno	/* List structure to add delete pending entries to */
272325618Ssbruno	struct lio_stailq_head	head;
273325618Ssbruno
274325618Ssbruno	/* A lock for this response list */
275325618Ssbruno	struct mtx		lock;
276325618Ssbruno
277325618Ssbruno	volatile uint32_t	alloc_buf_count;
278325618Ssbruno};
279325618Ssbruno
280325618Ssbruno#define LIO_INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \
281325618Ssbruno		(((octeon_dev_ptr)->instr_queue[iq_no]->stats.field) += count)
282325618Ssbruno
283325618Ssbrunoint	lio_setup_sc_buffer_pool(struct octeon_device *oct);
284325618Ssbrunoint	lio_free_sc_buffer_pool(struct octeon_device *oct);
285325618Ssbrunostruct lio_soft_command	*lio_alloc_soft_command(struct octeon_device *oct,
286325618Ssbruno						uint32_t datasize,
287325618Ssbruno						uint32_t rdatasize,
288325618Ssbruno						uint32_t ctxsize);
289325618Ssbrunovoid	lio_free_soft_command(struct octeon_device *oct,
290325618Ssbruno			      struct lio_soft_command *sc);
291325618Ssbruno
292325618Ssbruno/*
293325618Ssbruno *  lio_init_instr_queue()
294325618Ssbruno *  @param octeon_dev      - pointer to the octeon device structure.
295325618Ssbruno *  @param txpciq          - queue to be initialized (0 <= q_no <= 3).
296325618Ssbruno *
297325618Ssbruno *  Called at driver init time for each input queue. iq_conf has the
298325618Ssbruno *  configuration parameters for the queue.
299325618Ssbruno *
300325618Ssbruno *  @return  Success: 0   Failure: 1
301325618Ssbruno */
302325618Ssbrunoint	lio_init_instr_queue(struct octeon_device *octeon_dev,
303325618Ssbruno			     union octeon_txpciq txpciq, uint32_t num_descs);
304325618Ssbruno
305325618Ssbruno/*
306325618Ssbruno *  lio_delete_instr_queue()
307325618Ssbruno *  @param octeon_dev      - pointer to the octeon device structure.
308325618Ssbruno *  @param iq_no           - queue to be deleted
309325618Ssbruno *
310325618Ssbruno *  Called at driver unload time for each input queue. Deletes all
311325618Ssbruno *  allocated resources for the input queue.
312325618Ssbruno *
313325618Ssbruno *  @return  Success: 0   Failure: 1
314325618Ssbruno */
315325618Ssbrunoint	lio_delete_instr_queue(struct octeon_device *octeon_dev,
316325618Ssbruno			       uint32_t iq_no);
317325618Ssbruno
318325618Ssbrunoint	lio_wait_for_instr_fetch(struct octeon_device *oct);
319325618Ssbruno
320325618Ssbrunoint	lio_process_iq_request_list(struct octeon_device *oct,
321325618Ssbruno				    struct lio_instr_queue *iq,
322325618Ssbruno				    uint32_t budget);
323325618Ssbruno
324325618Ssbrunoint	lio_send_command(struct octeon_device *oct, uint32_t iq_no,
325325618Ssbruno			 uint32_t force_db, void *cmd, void *buf,
326325618Ssbruno			 uint32_t datasize, uint32_t reqtype);
327325618Ssbruno
328325618Ssbrunovoid	lio_prepare_soft_command(struct octeon_device *oct,
329325618Ssbruno				 struct lio_soft_command *sc,
330325618Ssbruno				 uint8_t opcode, uint8_t subcode,
331325618Ssbruno				 uint32_t irh_ossp, uint64_t ossp0,
332325618Ssbruno				 uint64_t ossp1);
333325618Ssbruno
334325618Ssbrunoint	lio_send_soft_command(struct octeon_device *oct,
335325618Ssbruno			      struct lio_soft_command *sc);
336325618Ssbruno
337325618Ssbrunoint	lio_setup_iq(struct octeon_device *oct, int ifidx,
338325618Ssbruno		     int q_index, union octeon_txpciq iq_no,
339325618Ssbruno		     uint32_t num_descs);
340325618Ssbrunoint	lio_flush_iq(struct octeon_device *oct, struct lio_instr_queue *iq,
341325618Ssbruno		     uint32_t budget);
342325618Ssbruno#endif	/* __LIO_IQ_H__ */
343