xref: /freebsd/sys/dev/liquidio/base/lio_iq.h (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
1*f173c2b7SSean Bruno /*
2*f173c2b7SSean Bruno  *   BSD LICENSE
3*f173c2b7SSean Bruno  *
4*f173c2b7SSean Bruno  *   Copyright(c) 2017 Cavium, Inc.. All rights reserved.
5*f173c2b7SSean Bruno  *   All rights reserved.
6*f173c2b7SSean Bruno  *
7*f173c2b7SSean Bruno  *   Redistribution and use in source and binary forms, with or without
8*f173c2b7SSean Bruno  *   modification, are permitted provided that the following conditions
9*f173c2b7SSean Bruno  *   are met:
10*f173c2b7SSean Bruno  *
11*f173c2b7SSean Bruno  *     * Redistributions of source code must retain the above copyright
12*f173c2b7SSean Bruno  *       notice, this list of conditions and the following disclaimer.
13*f173c2b7SSean Bruno  *     * Redistributions in binary form must reproduce the above copyright
14*f173c2b7SSean Bruno  *       notice, this list of conditions and the following disclaimer in
15*f173c2b7SSean Bruno  *       the documentation and/or other materials provided with the
16*f173c2b7SSean Bruno  *       distribution.
17*f173c2b7SSean Bruno  *     * Neither the name of Cavium, Inc. nor the names of its
18*f173c2b7SSean Bruno  *       contributors may be used to endorse or promote products derived
19*f173c2b7SSean Bruno  *       from this software without specific prior written permission.
20*f173c2b7SSean Bruno  *
21*f173c2b7SSean Bruno  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*f173c2b7SSean Bruno  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*f173c2b7SSean Bruno  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24*f173c2b7SSean Bruno  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25*f173c2b7SSean Bruno  *   OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26*f173c2b7SSean Bruno  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27*f173c2b7SSean Bruno  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28*f173c2b7SSean Bruno  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29*f173c2b7SSean Bruno  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30*f173c2b7SSean Bruno  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31*f173c2b7SSean Bruno  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*f173c2b7SSean Bruno  */
33*f173c2b7SSean Bruno 
34*f173c2b7SSean Bruno /*   \file  lio_iq.h
35*f173c2b7SSean Bruno  *   \brief Host Driver: Implementation of Octeon input queues. "Input" is
36*f173c2b7SSean Bruno  *   with respect to the Octeon device on the NIC. From this driver's
37*f173c2b7SSean Bruno  *   point of view they are egress queues.
38*f173c2b7SSean Bruno  */
39*f173c2b7SSean Bruno 
40*f173c2b7SSean Bruno #ifndef __LIO_IQ_H__
41*f173c2b7SSean Bruno #define __LIO_IQ_H__
42*f173c2b7SSean Bruno 
43*f173c2b7SSean Bruno #define LIO_IQ_SEND_OK          0
44*f173c2b7SSean Bruno #define LIO_IQ_SEND_STOP        1
45*f173c2b7SSean Bruno #define LIO_IQ_SEND_FAILED     -1
46*f173c2b7SSean Bruno 
47*f173c2b7SSean Bruno /*-------------------------  INSTRUCTION QUEUE --------------------------*/
48*f173c2b7SSean Bruno 
49*f173c2b7SSean Bruno #define LIO_REQTYPE_NONE                 0
50*f173c2b7SSean Bruno #define LIO_REQTYPE_NORESP_NET           1
51*f173c2b7SSean Bruno #define LIO_REQTYPE_NORESP_NET_SG        2
52*f173c2b7SSean Bruno #define LIO_REQTYPE_RESP_NET             3
53*f173c2b7SSean Bruno #define LIO_REQTYPE_SOFT_COMMAND         4
54*f173c2b7SSean Bruno 
55*f173c2b7SSean Bruno /*
56*f173c2b7SSean Bruno  * This structure is used by NIC driver to store information required
57*f173c2b7SSean Bruno  * to free the mbuf when the packet has been fetched by Octeon.
58*f173c2b7SSean Bruno  * Bytes offset below assume worst-case of a 64-bit system.
59*f173c2b7SSean Bruno  */
60*f173c2b7SSean Bruno struct lio_mbuf_free_info {
61*f173c2b7SSean Bruno 	/* Pointer to mbuf. */
62*f173c2b7SSean Bruno 	struct mbuf		*mb;
63*f173c2b7SSean Bruno 
64*f173c2b7SSean Bruno 	/* Pointer to gather list. */
65*f173c2b7SSean Bruno 	struct lio_gather	*g;
66*f173c2b7SSean Bruno 
67*f173c2b7SSean Bruno 	bus_dmamap_t		map;
68*f173c2b7SSean Bruno };
69*f173c2b7SSean Bruno 
70*f173c2b7SSean Bruno struct lio_request_list {
71*f173c2b7SSean Bruno 	uint32_t			reqtype;
72*f173c2b7SSean Bruno 	void				*buf;
73*f173c2b7SSean Bruno 	bus_dmamap_t			map;
74*f173c2b7SSean Bruno 	struct lio_mbuf_free_info	finfo;
75*f173c2b7SSean Bruno };
76*f173c2b7SSean Bruno 
77*f173c2b7SSean Bruno /* Input Queue statistics. Each input queue has four stats fields. */
78*f173c2b7SSean Bruno struct lio_iq_stats {
79*f173c2b7SSean Bruno 	uint64_t	instr_posted;		/**< Instructions posted to this queue. */
80*f173c2b7SSean Bruno 	uint64_t	instr_processed;	/**< Instructions processed in this queue. */
81*f173c2b7SSean Bruno 	uint64_t	instr_dropped;		/**< Instructions that could not be processed */
82*f173c2b7SSean Bruno 	uint64_t	bytes_sent;		/**< Bytes sent through this queue. */
83*f173c2b7SSean Bruno 	uint64_t	sgentry_sent;		/**< Gather entries sent through this queue. */
84*f173c2b7SSean Bruno 	uint64_t	tx_done;		/**< Num of packets sent to network. */
85*f173c2b7SSean Bruno 	uint64_t	tx_iq_busy;		/**< Numof times this iq was found to be full. */
86*f173c2b7SSean Bruno 	uint64_t	tx_dropped;		/**< Numof pkts dropped dueto xmitpath errors. */
87*f173c2b7SSean Bruno 	uint64_t	tx_tot_bytes;		/**< Total count of bytes sento to network. */
88*f173c2b7SSean Bruno 	uint64_t	tx_gso;			/* count of tso */
89*f173c2b7SSean Bruno 	uint64_t	tx_vxlan;		/* tunnel */
90*f173c2b7SSean Bruno 	uint64_t	tx_dmamap_fail;
91*f173c2b7SSean Bruno 	uint64_t	tx_restart;
92*f173c2b7SSean Bruno 	uint64_t	mbuf_defrag_failed;
93*f173c2b7SSean Bruno };
94*f173c2b7SSean Bruno 
95*f173c2b7SSean Bruno /*
96*f173c2b7SSean Bruno  *  The instruction (input) queue.
97*f173c2b7SSean Bruno  *  The input queue is used to post raw (instruction) mode data or packet
98*f173c2b7SSean Bruno  *  data to Octeon device from the host. Each input queue for
99*f173c2b7SSean Bruno  *  a Octeon device has one such structure to represent it.
100*f173c2b7SSean Bruno  */
101*f173c2b7SSean Bruno struct lio_instr_queue {
102*f173c2b7SSean Bruno 	struct octeon_device	*oct_dev;
103*f173c2b7SSean Bruno 
104*f173c2b7SSean Bruno 	/* A lock to protect access to the input ring.  */
105*f173c2b7SSean Bruno 	struct mtx		lock;
106*f173c2b7SSean Bruno 
107*f173c2b7SSean Bruno 	/* A lock to protect while enqueue to the input ring.  */
108*f173c2b7SSean Bruno 	struct mtx		enq_lock;
109*f173c2b7SSean Bruno 
110*f173c2b7SSean Bruno 	/* A lock to protect while posting on the ring.  */
111*f173c2b7SSean Bruno 	struct mtx		post_lock;
112*f173c2b7SSean Bruno 
113*f173c2b7SSean Bruno 	uint32_t		pkt_in_done;
114*f173c2b7SSean Bruno 
115*f173c2b7SSean Bruno 	/* A lock to protect access to the input ring. */
116*f173c2b7SSean Bruno 	struct mtx		iq_flush_running_lock;
117*f173c2b7SSean Bruno 
118*f173c2b7SSean Bruno 	/* Flag that indicates if the queue uses 64 byte commands. */
119*f173c2b7SSean Bruno 	uint32_t		iqcmd_64B:1;
120*f173c2b7SSean Bruno 
121*f173c2b7SSean Bruno 	/* Queue info. */
122*f173c2b7SSean Bruno 	union octeon_txpciq	txpciq;
123*f173c2b7SSean Bruno 
124*f173c2b7SSean Bruno 	uint32_t		rsvd:17;
125*f173c2b7SSean Bruno 
126*f173c2b7SSean Bruno 	uint32_t		status:8;
127*f173c2b7SSean Bruno 
128*f173c2b7SSean Bruno 	/* Maximum no. of instructions in this queue. */
129*f173c2b7SSean Bruno 	uint32_t		max_count;
130*f173c2b7SSean Bruno 
131*f173c2b7SSean Bruno 	/* Index in input ring where the driver should write the next packet */
132*f173c2b7SSean Bruno 	uint32_t		host_write_index;
133*f173c2b7SSean Bruno 
134*f173c2b7SSean Bruno 	/*
135*f173c2b7SSean Bruno 	 * Index in input ring where Octeon is expected to read the next
136*f173c2b7SSean Bruno 	 * packet.
137*f173c2b7SSean Bruno 	 */
138*f173c2b7SSean Bruno 	uint32_t		octeon_read_index;
139*f173c2b7SSean Bruno 
140*f173c2b7SSean Bruno 	/*
141*f173c2b7SSean Bruno 	 * This index aids in finding the window in the queue where Octeon
142*f173c2b7SSean Bruno 	 * has read the commands.
143*f173c2b7SSean Bruno 	 */
144*f173c2b7SSean Bruno 	uint32_t		flush_index;
145*f173c2b7SSean Bruno 
146*f173c2b7SSean Bruno 	/* This field keeps track of the instructions pending in this queue. */
147*f173c2b7SSean Bruno 	volatile int		instr_pending;
148*f173c2b7SSean Bruno 
149*f173c2b7SSean Bruno 	uint32_t		reset_instr_cnt;
150*f173c2b7SSean Bruno 
151*f173c2b7SSean Bruno 	/* Pointer to the Virtual Base addr of the input ring. */
152*f173c2b7SSean Bruno 	uint8_t			*base_addr;
153*f173c2b7SSean Bruno 	bus_dma_tag_t		txtag;
154*f173c2b7SSean Bruno 
155*f173c2b7SSean Bruno 	struct lio_request_list	*request_list;
156*f173c2b7SSean Bruno 
157*f173c2b7SSean Bruno 	struct buf_ring		*br;
158*f173c2b7SSean Bruno 
159*f173c2b7SSean Bruno 	/* Octeon doorbell register for the ring. */
160*f173c2b7SSean Bruno 	uint32_t		doorbell_reg;
161*f173c2b7SSean Bruno 
162*f173c2b7SSean Bruno 	/* Octeon instruction count register for this ring. */
163*f173c2b7SSean Bruno 	uint32_t		inst_cnt_reg;
164*f173c2b7SSean Bruno 
165*f173c2b7SSean Bruno 	/* Number of instructions pending to be posted to Octeon. */
166*f173c2b7SSean Bruno 	uint32_t		fill_cnt;
167*f173c2b7SSean Bruno 
168*f173c2b7SSean Bruno 	/* The last time that the doorbell was rung. */
169*f173c2b7SSean Bruno 	uint64_t		last_db_time;
170*f173c2b7SSean Bruno 
171*f173c2b7SSean Bruno 	/*
172*f173c2b7SSean Bruno 	 * The doorbell timeout. If the doorbell was not rung for this time
173*f173c2b7SSean Bruno 	 * and fill_cnt is non-zero, ring the doorbell again.
174*f173c2b7SSean Bruno 	 */
175*f173c2b7SSean Bruno 	uint32_t		db_timeout;
176*f173c2b7SSean Bruno 
177*f173c2b7SSean Bruno 	/* Statistics for this input queue. */
178*f173c2b7SSean Bruno 	struct lio_iq_stats	stats;
179*f173c2b7SSean Bruno 
180*f173c2b7SSean Bruno 	/* DMA mapped base address of the input descriptor ring. */
181*f173c2b7SSean Bruno 	uint64_t		base_addr_dma;
182*f173c2b7SSean Bruno 
183*f173c2b7SSean Bruno 	/* Application context */
184*f173c2b7SSean Bruno 	void			*app_ctx;
185*f173c2b7SSean Bruno 
186*f173c2b7SSean Bruno 	/* network stack queue index */
187*f173c2b7SSean Bruno 	int			q_index;
188*f173c2b7SSean Bruno 
189*f173c2b7SSean Bruno 	/* os ifidx associated with this queue */
190*f173c2b7SSean Bruno 	int			ifidx;
191*f173c2b7SSean Bruno 
192*f173c2b7SSean Bruno };
193*f173c2b7SSean Bruno 
194*f173c2b7SSean Bruno /*----------------------  INSTRUCTION FORMAT ----------------------------*/
195*f173c2b7SSean Bruno 
196*f173c2b7SSean Bruno struct lio_instr3_64B {
197*f173c2b7SSean Bruno 	/* Pointer where the input data is available. */
198*f173c2b7SSean Bruno 	uint64_t	dptr;
199*f173c2b7SSean Bruno 
200*f173c2b7SSean Bruno 	/* Instruction Header. */
201*f173c2b7SSean Bruno 	uint64_t	ih3;
202*f173c2b7SSean Bruno 
203*f173c2b7SSean Bruno 	/* Instruction Header. */
204*f173c2b7SSean Bruno 	uint64_t	pki_ih3;
205*f173c2b7SSean Bruno 
206*f173c2b7SSean Bruno 	/* Input Request Header. */
207*f173c2b7SSean Bruno 	uint64_t	irh;
208*f173c2b7SSean Bruno 
209*f173c2b7SSean Bruno 	/* opcode/subcode specific parameters */
210*f173c2b7SSean Bruno 	uint64_t	ossp[2];
211*f173c2b7SSean Bruno 
212*f173c2b7SSean Bruno 	/* Return Data Parameters */
213*f173c2b7SSean Bruno 	uint64_t	rdp;
214*f173c2b7SSean Bruno 
215*f173c2b7SSean Bruno 	/*
216*f173c2b7SSean Bruno 	 * Pointer where the response for a RAW mode packet will be written
217*f173c2b7SSean Bruno 	 * by Octeon.
218*f173c2b7SSean Bruno 	 */
219*f173c2b7SSean Bruno 	uint64_t	rptr;
220*f173c2b7SSean Bruno 
221*f173c2b7SSean Bruno };
222*f173c2b7SSean Bruno 
223*f173c2b7SSean Bruno union lio_instr_64B {
224*f173c2b7SSean Bruno 	struct lio_instr3_64B	cmd3;
225*f173c2b7SSean Bruno };
226*f173c2b7SSean Bruno 
227*f173c2b7SSean Bruno /* The size of each buffer in soft command buffer pool */
228*f173c2b7SSean Bruno #define LIO_SOFT_COMMAND_BUFFER_SIZE	2048
229*f173c2b7SSean Bruno 
230*f173c2b7SSean Bruno struct lio_soft_command {
231*f173c2b7SSean Bruno 	/* Soft command buffer info. */
232*f173c2b7SSean Bruno 	struct lio_stailq_node	node;
233*f173c2b7SSean Bruno 	uint64_t		dma_addr;
234*f173c2b7SSean Bruno 	uint32_t		size;
235*f173c2b7SSean Bruno 
236*f173c2b7SSean Bruno 	/* Command and return status */
237*f173c2b7SSean Bruno 	union lio_instr_64B	cmd;
238*f173c2b7SSean Bruno 
239*f173c2b7SSean Bruno #define COMPLETION_WORD_INIT    0xffffffffffffffffULL
240*f173c2b7SSean Bruno 	uint64_t		*status_word;
241*f173c2b7SSean Bruno 
242*f173c2b7SSean Bruno 	/* Data buffer info */
243*f173c2b7SSean Bruno 	void			*virtdptr;
244*f173c2b7SSean Bruno 	uint64_t		dmadptr;
245*f173c2b7SSean Bruno 	uint32_t		datasize;
246*f173c2b7SSean Bruno 
247*f173c2b7SSean Bruno 	/* Return buffer info */
248*f173c2b7SSean Bruno 	void			*virtrptr;
249*f173c2b7SSean Bruno 	uint64_t		dmarptr;
250*f173c2b7SSean Bruno 	uint32_t		rdatasize;
251*f173c2b7SSean Bruno 
252*f173c2b7SSean Bruno 	/* Context buffer info */
253*f173c2b7SSean Bruno 	void			*ctxptr;
254*f173c2b7SSean Bruno 	uint32_t		ctxsize;
255*f173c2b7SSean Bruno 
256*f173c2b7SSean Bruno 	/* Time out and callback */
257*f173c2b7SSean Bruno 	int			wait_time;
258*f173c2b7SSean Bruno 	int			timeout;
259*f173c2b7SSean Bruno 	uint32_t		iq_no;
260*f173c2b7SSean Bruno 	void			(*callback) (struct octeon_device *, uint32_t,
261*f173c2b7SSean Bruno 					     void *);
262*f173c2b7SSean Bruno 	void			*callback_arg;
263*f173c2b7SSean Bruno };
264*f173c2b7SSean Bruno 
265*f173c2b7SSean Bruno /* Maximum number of buffers to allocate into soft command buffer pool */
266*f173c2b7SSean Bruno #define LIO_MAX_SOFT_COMMAND_BUFFERS	256
267*f173c2b7SSean Bruno 
268*f173c2b7SSean Bruno /* Head of a soft command buffer pool. */
269*f173c2b7SSean Bruno struct lio_sc_buffer_pool {
270*f173c2b7SSean Bruno 	/* List structure to add delete pending entries to */
271*f173c2b7SSean Bruno 	struct lio_stailq_head	head;
272*f173c2b7SSean Bruno 
273*f173c2b7SSean Bruno 	/* A lock for this response list */
274*f173c2b7SSean Bruno 	struct mtx		lock;
275*f173c2b7SSean Bruno 
276*f173c2b7SSean Bruno 	volatile uint32_t	alloc_buf_count;
277*f173c2b7SSean Bruno };
278*f173c2b7SSean Bruno 
279*f173c2b7SSean Bruno #define LIO_INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count) \
280*f173c2b7SSean Bruno 		(((octeon_dev_ptr)->instr_queue[iq_no]->stats.field) += count)
281*f173c2b7SSean Bruno 
282*f173c2b7SSean Bruno int	lio_setup_sc_buffer_pool(struct octeon_device *oct);
283*f173c2b7SSean Bruno int	lio_free_sc_buffer_pool(struct octeon_device *oct);
284*f173c2b7SSean Bruno struct lio_soft_command	*lio_alloc_soft_command(struct octeon_device *oct,
285*f173c2b7SSean Bruno 						uint32_t datasize,
286*f173c2b7SSean Bruno 						uint32_t rdatasize,
287*f173c2b7SSean Bruno 						uint32_t ctxsize);
288*f173c2b7SSean Bruno void	lio_free_soft_command(struct octeon_device *oct,
289*f173c2b7SSean Bruno 			      struct lio_soft_command *sc);
290*f173c2b7SSean Bruno 
291*f173c2b7SSean Bruno /*
292*f173c2b7SSean Bruno  *  lio_init_instr_queue()
293*f173c2b7SSean Bruno  *  @param octeon_dev      - pointer to the octeon device structure.
294*f173c2b7SSean Bruno  *  @param txpciq          - queue to be initialized (0 <= q_no <= 3).
295*f173c2b7SSean Bruno  *
296*f173c2b7SSean Bruno  *  Called at driver init time for each input queue. iq_conf has the
297*f173c2b7SSean Bruno  *  configuration parameters for the queue.
298*f173c2b7SSean Bruno  *
299*f173c2b7SSean Bruno  *  @return  Success: 0   Failure: 1
300*f173c2b7SSean Bruno  */
301*f173c2b7SSean Bruno int	lio_init_instr_queue(struct octeon_device *octeon_dev,
302*f173c2b7SSean Bruno 			     union octeon_txpciq txpciq, uint32_t num_descs);
303*f173c2b7SSean Bruno 
304*f173c2b7SSean Bruno /*
305*f173c2b7SSean Bruno  *  lio_delete_instr_queue()
306*f173c2b7SSean Bruno  *  @param octeon_dev      - pointer to the octeon device structure.
307*f173c2b7SSean Bruno  *  @param iq_no           - queue to be deleted
308*f173c2b7SSean Bruno  *
309*f173c2b7SSean Bruno  *  Called at driver unload time for each input queue. Deletes all
310*f173c2b7SSean Bruno  *  allocated resources for the input queue.
311*f173c2b7SSean Bruno  *
312*f173c2b7SSean Bruno  *  @return  Success: 0   Failure: 1
313*f173c2b7SSean Bruno  */
314*f173c2b7SSean Bruno int	lio_delete_instr_queue(struct octeon_device *octeon_dev,
315*f173c2b7SSean Bruno 			       uint32_t iq_no);
316*f173c2b7SSean Bruno 
317*f173c2b7SSean Bruno int	lio_wait_for_instr_fetch(struct octeon_device *oct);
318*f173c2b7SSean Bruno 
319*f173c2b7SSean Bruno int	lio_process_iq_request_list(struct octeon_device *oct,
320*f173c2b7SSean Bruno 				    struct lio_instr_queue *iq,
321*f173c2b7SSean Bruno 				    uint32_t budget);
322*f173c2b7SSean Bruno 
323*f173c2b7SSean Bruno int	lio_send_command(struct octeon_device *oct, uint32_t iq_no,
324*f173c2b7SSean Bruno 			 uint32_t force_db, void *cmd, void *buf,
325*f173c2b7SSean Bruno 			 uint32_t datasize, uint32_t reqtype);
326*f173c2b7SSean Bruno 
327*f173c2b7SSean Bruno void	lio_prepare_soft_command(struct octeon_device *oct,
328*f173c2b7SSean Bruno 				 struct lio_soft_command *sc,
329*f173c2b7SSean Bruno 				 uint8_t opcode, uint8_t subcode,
330*f173c2b7SSean Bruno 				 uint32_t irh_ossp, uint64_t ossp0,
331*f173c2b7SSean Bruno 				 uint64_t ossp1);
332*f173c2b7SSean Bruno 
333*f173c2b7SSean Bruno int	lio_send_soft_command(struct octeon_device *oct,
334*f173c2b7SSean Bruno 			      struct lio_soft_command *sc);
335*f173c2b7SSean Bruno 
336*f173c2b7SSean Bruno int	lio_setup_iq(struct octeon_device *oct, int ifidx,
337*f173c2b7SSean Bruno 		     int q_index, union octeon_txpciq iq_no,
338*f173c2b7SSean Bruno 		     uint32_t num_descs);
339*f173c2b7SSean Bruno int	lio_flush_iq(struct octeon_device *oct, struct lio_instr_queue *iq,
340*f173c2b7SSean Bruno 		     uint32_t budget);
341*f173c2b7SSean Bruno #endif	/* __LIO_IQ_H__ */
342