xref: /OK3568_Linux_fs/kernel/include/soc/fsl/qman.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Redistribution and use in source and binary forms, with or without
4*4882a593Smuzhiyun  * modification, are permitted provided that the following conditions are met:
5*4882a593Smuzhiyun  *     * Redistributions of source code must retain the above copyright
6*4882a593Smuzhiyun  *	 notice, this list of conditions and the following disclaimer.
7*4882a593Smuzhiyun  *     * Redistributions in binary form must reproduce the above copyright
8*4882a593Smuzhiyun  *	 notice, this list of conditions and the following disclaimer in the
9*4882a593Smuzhiyun  *	 documentation and/or other materials provided with the distribution.
10*4882a593Smuzhiyun  *     * Neither the name of Freescale Semiconductor nor the
11*4882a593Smuzhiyun  *	 names of its contributors may be used to endorse or promote products
12*4882a593Smuzhiyun  *	 derived from this software without specific prior written permission.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * ALTERNATIVELY, this software may be distributed under the terms of the
15*4882a593Smuzhiyun  * GNU General Public License ("GPL") as published by the Free Software
16*4882a593Smuzhiyun  * Foundation, either version 2 of that License or (at your option) any
17*4882a593Smuzhiyun  * later version.
18*4882a593Smuzhiyun  *
19*4882a593Smuzhiyun  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20*4882a593Smuzhiyun  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21*4882a593Smuzhiyun  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22*4882a593Smuzhiyun  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23*4882a593Smuzhiyun  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24*4882a593Smuzhiyun  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*4882a593Smuzhiyun  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26*4882a593Smuzhiyun  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*4882a593Smuzhiyun  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28*4882a593Smuzhiyun  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #ifndef __FSL_QMAN_H
32*4882a593Smuzhiyun #define __FSL_QMAN_H
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #include <linux/bitops.h>
35*4882a593Smuzhiyun #include <linux/device.h>
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /* Hardware constants */
38*4882a593Smuzhiyun #define QM_CHANNEL_SWPORTAL0 0
39*4882a593Smuzhiyun #define QMAN_CHANNEL_POOL1 0x21
40*4882a593Smuzhiyun #define QMAN_CHANNEL_CAAM 0x80
41*4882a593Smuzhiyun #define QMAN_CHANNEL_POOL1_REV3 0x401
42*4882a593Smuzhiyun #define QMAN_CHANNEL_CAAM_REV3 0x840
43*4882a593Smuzhiyun extern u16 qm_channel_pool1;
44*4882a593Smuzhiyun extern u16 qm_channel_caam;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun /* Portal processing (interrupt) sources */
47*4882a593Smuzhiyun #define QM_PIRQ_CSCI	0x00100000	/* Congestion State Change */
48*4882a593Smuzhiyun #define QM_PIRQ_EQCI	0x00080000	/* Enqueue Command Committed */
49*4882a593Smuzhiyun #define QM_PIRQ_EQRI	0x00040000	/* EQCR Ring (below threshold) */
50*4882a593Smuzhiyun #define QM_PIRQ_DQRI	0x00020000	/* DQRR Ring (non-empty) */
51*4882a593Smuzhiyun #define QM_PIRQ_MRI	0x00010000	/* MR Ring (non-empty) */
52*4882a593Smuzhiyun /*
53*4882a593Smuzhiyun  * This mask contains all the interrupt sources that need handling except DQRI,
54*4882a593Smuzhiyun  * ie. that if present should trigger slow-path processing.
55*4882a593Smuzhiyun  */
56*4882a593Smuzhiyun #define QM_PIRQ_SLOW	(QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
57*4882a593Smuzhiyun 			 QM_PIRQ_MRI)
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /* For qman_static_dequeue_*** APIs */
60*4882a593Smuzhiyun #define QM_SDQCR_CHANNELS_POOL_MASK	0x00007fff
61*4882a593Smuzhiyun /* for n in [1,15] */
62*4882a593Smuzhiyun #define QM_SDQCR_CHANNELS_POOL(n)	(0x00008000 >> (n))
63*4882a593Smuzhiyun /* for conversion from n of qm_channel */
QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)64*4882a593Smuzhiyun static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* --- QMan data structures (and associated constants) --- */
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /* "Frame Descriptor (FD)" */
72*4882a593Smuzhiyun struct qm_fd {
73*4882a593Smuzhiyun 	union {
74*4882a593Smuzhiyun 		struct {
75*4882a593Smuzhiyun 			u8 cfg8b_w1;
76*4882a593Smuzhiyun 			u8 bpid;	/* Buffer Pool ID */
77*4882a593Smuzhiyun 			u8 cfg8b_w3;
78*4882a593Smuzhiyun 			u8 addr_hi;	/* high 8-bits of 40-bit address */
79*4882a593Smuzhiyun 			__be32 addr_lo;	/* low 32-bits of 40-bit address */
80*4882a593Smuzhiyun 		} __packed;
81*4882a593Smuzhiyun 		__be64 data;
82*4882a593Smuzhiyun 	};
83*4882a593Smuzhiyun 	__be32 cfg;	/* format, offset, length / congestion */
84*4882a593Smuzhiyun 	union {
85*4882a593Smuzhiyun 		__be32 cmd;
86*4882a593Smuzhiyun 		__be32 status;
87*4882a593Smuzhiyun 	};
88*4882a593Smuzhiyun } __aligned(8);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun #define QM_FD_FORMAT_SG		BIT(31)
91*4882a593Smuzhiyun #define QM_FD_FORMAT_LONG	BIT(30)
92*4882a593Smuzhiyun #define QM_FD_FORMAT_COMPOUND	BIT(29)
93*4882a593Smuzhiyun #define QM_FD_FORMAT_MASK	GENMASK(31, 29)
94*4882a593Smuzhiyun #define QM_FD_OFF_SHIFT		20
95*4882a593Smuzhiyun #define QM_FD_OFF_MASK		GENMASK(28, 20)
96*4882a593Smuzhiyun #define QM_FD_LEN_MASK		GENMASK(19, 0)
97*4882a593Smuzhiyun #define QM_FD_LEN_BIG_MASK	GENMASK(28, 0)
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun enum qm_fd_format {
100*4882a593Smuzhiyun 	/*
101*4882a593Smuzhiyun 	 * 'contig' implies a contiguous buffer, whereas 'sg' implies a
102*4882a593Smuzhiyun 	 * scatter-gather table. 'big' implies a 29-bit length with no offset
103*4882a593Smuzhiyun 	 * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
104*4882a593Smuzhiyun 	 * implies a s/g-like table, where each entry itself represents a frame
105*4882a593Smuzhiyun 	 * (contiguous or scatter-gather) and the 29-bit "length" is
106*4882a593Smuzhiyun 	 * interpreted purely for congestion calculations, ie. a "congestion
107*4882a593Smuzhiyun 	 * weight".
108*4882a593Smuzhiyun 	 */
109*4882a593Smuzhiyun 	qm_fd_contig = 0,
110*4882a593Smuzhiyun 	qm_fd_contig_big = QM_FD_FORMAT_LONG,
111*4882a593Smuzhiyun 	qm_fd_sg = QM_FD_FORMAT_SG,
112*4882a593Smuzhiyun 	qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
113*4882a593Smuzhiyun 	qm_fd_compound = QM_FD_FORMAT_COMPOUND
114*4882a593Smuzhiyun };
115*4882a593Smuzhiyun 
qm_fd_addr(const struct qm_fd * fd)116*4882a593Smuzhiyun static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun 	return be64_to_cpu(fd->data) & 0xffffffffffLLU;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun 
qm_fd_addr_get64(const struct qm_fd * fd)121*4882a593Smuzhiyun static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 	return be64_to_cpu(fd->data) & 0xffffffffffLLU;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
qm_fd_addr_set64(struct qm_fd * fd,u64 addr)126*4882a593Smuzhiyun static inline void qm_fd_addr_set64(struct qm_fd *fd, u64 addr)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	fd->addr_hi = upper_32_bits(addr);
129*4882a593Smuzhiyun 	fd->addr_lo = cpu_to_be32(lower_32_bits(addr));
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /*
133*4882a593Smuzhiyun  * The 'format' field indicates the interpretation of the remaining
134*4882a593Smuzhiyun  * 29 bits of the 32-bit word.
135*4882a593Smuzhiyun  * If 'format' is _contig or _sg, 20b length and 9b offset.
136*4882a593Smuzhiyun  * If 'format' is _contig_big or _sg_big, 29b length.
137*4882a593Smuzhiyun  * If 'format' is _compound, 29b "congestion weight".
138*4882a593Smuzhiyun  */
qm_fd_get_format(const struct qm_fd * fd)139*4882a593Smuzhiyun static inline enum qm_fd_format qm_fd_get_format(const struct qm_fd *fd)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	return be32_to_cpu(fd->cfg) & QM_FD_FORMAT_MASK;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
qm_fd_get_offset(const struct qm_fd * fd)144*4882a593Smuzhiyun static inline int qm_fd_get_offset(const struct qm_fd *fd)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun 	return (be32_to_cpu(fd->cfg) & QM_FD_OFF_MASK) >> QM_FD_OFF_SHIFT;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun 
qm_fd_get_length(const struct qm_fd * fd)149*4882a593Smuzhiyun static inline int qm_fd_get_length(const struct qm_fd *fd)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun 	return be32_to_cpu(fd->cfg) & QM_FD_LEN_MASK;
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
qm_fd_get_len_big(const struct qm_fd * fd)154*4882a593Smuzhiyun static inline int qm_fd_get_len_big(const struct qm_fd *fd)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun 	return be32_to_cpu(fd->cfg) & QM_FD_LEN_BIG_MASK;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun 
qm_fd_set_param(struct qm_fd * fd,enum qm_fd_format fmt,int off,int len)159*4882a593Smuzhiyun static inline void qm_fd_set_param(struct qm_fd *fd, enum qm_fd_format fmt,
160*4882a593Smuzhiyun 				   int off, int len)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun 	fd->cfg = cpu_to_be32(fmt | (len & QM_FD_LEN_BIG_MASK) |
163*4882a593Smuzhiyun 			      ((off << QM_FD_OFF_SHIFT) & QM_FD_OFF_MASK));
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun #define qm_fd_set_contig(fd, off, len) \
167*4882a593Smuzhiyun 	qm_fd_set_param(fd, qm_fd_contig, off, len)
168*4882a593Smuzhiyun #define qm_fd_set_sg(fd, off, len) qm_fd_set_param(fd, qm_fd_sg, off, len)
169*4882a593Smuzhiyun #define qm_fd_set_contig_big(fd, len) \
170*4882a593Smuzhiyun 	qm_fd_set_param(fd, qm_fd_contig_big, 0, len)
171*4882a593Smuzhiyun #define qm_fd_set_sg_big(fd, len) qm_fd_set_param(fd, qm_fd_sg_big, 0, len)
172*4882a593Smuzhiyun #define qm_fd_set_compound(fd, len) qm_fd_set_param(fd, qm_fd_compound, 0, len)
173*4882a593Smuzhiyun 
qm_fd_clear_fd(struct qm_fd * fd)174*4882a593Smuzhiyun static inline void qm_fd_clear_fd(struct qm_fd *fd)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun 	fd->data = 0;
177*4882a593Smuzhiyun 	fd->cfg = 0;
178*4882a593Smuzhiyun 	fd->cmd = 0;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun /* Scatter/Gather table entry */
182*4882a593Smuzhiyun struct qm_sg_entry {
183*4882a593Smuzhiyun 	union {
184*4882a593Smuzhiyun 		struct {
185*4882a593Smuzhiyun 			u8 __reserved1[3];
186*4882a593Smuzhiyun 			u8 addr_hi;	/* high 8-bits of 40-bit address */
187*4882a593Smuzhiyun 			__be32 addr_lo;	/* low 32-bits of 40-bit address */
188*4882a593Smuzhiyun 		};
189*4882a593Smuzhiyun 		__be64 data;
190*4882a593Smuzhiyun 	};
191*4882a593Smuzhiyun 	__be32 cfg;	/* E bit, F bit, length */
192*4882a593Smuzhiyun 	u8 __reserved2;
193*4882a593Smuzhiyun 	u8 bpid;
194*4882a593Smuzhiyun 	__be16 offset; /* 13-bit, _res[13-15]*/
195*4882a593Smuzhiyun } __packed;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun #define QM_SG_LEN_MASK	GENMASK(29, 0)
198*4882a593Smuzhiyun #define QM_SG_OFF_MASK	GENMASK(12, 0)
199*4882a593Smuzhiyun #define QM_SG_FIN	BIT(30)
200*4882a593Smuzhiyun #define QM_SG_EXT	BIT(31)
201*4882a593Smuzhiyun 
qm_sg_addr(const struct qm_sg_entry * sg)202*4882a593Smuzhiyun static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	return be64_to_cpu(sg->data) & 0xffffffffffLLU;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun 
qm_sg_entry_get64(const struct qm_sg_entry * sg)207*4882a593Smuzhiyun static inline u64 qm_sg_entry_get64(const struct qm_sg_entry *sg)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	return be64_to_cpu(sg->data) & 0xffffffffffLLU;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
qm_sg_entry_set64(struct qm_sg_entry * sg,u64 addr)212*4882a593Smuzhiyun static inline void qm_sg_entry_set64(struct qm_sg_entry *sg, u64 addr)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun 	sg->addr_hi = upper_32_bits(addr);
215*4882a593Smuzhiyun 	sg->addr_lo = cpu_to_be32(lower_32_bits(addr));
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
qm_sg_entry_is_final(const struct qm_sg_entry * sg)218*4882a593Smuzhiyun static inline bool qm_sg_entry_is_final(const struct qm_sg_entry *sg)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun 	return be32_to_cpu(sg->cfg) & QM_SG_FIN;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
qm_sg_entry_is_ext(const struct qm_sg_entry * sg)223*4882a593Smuzhiyun static inline bool qm_sg_entry_is_ext(const struct qm_sg_entry *sg)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	return be32_to_cpu(sg->cfg) & QM_SG_EXT;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
qm_sg_entry_get_len(const struct qm_sg_entry * sg)228*4882a593Smuzhiyun static inline int qm_sg_entry_get_len(const struct qm_sg_entry *sg)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	return be32_to_cpu(sg->cfg) & QM_SG_LEN_MASK;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
qm_sg_entry_set_len(struct qm_sg_entry * sg,int len)233*4882a593Smuzhiyun static inline void qm_sg_entry_set_len(struct qm_sg_entry *sg, int len)
234*4882a593Smuzhiyun {
235*4882a593Smuzhiyun 	sg->cfg = cpu_to_be32(len & QM_SG_LEN_MASK);
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun 
qm_sg_entry_set_f(struct qm_sg_entry * sg,int len)238*4882a593Smuzhiyun static inline void qm_sg_entry_set_f(struct qm_sg_entry *sg, int len)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun 	sg->cfg = cpu_to_be32(QM_SG_FIN | (len & QM_SG_LEN_MASK));
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
qm_sg_entry_get_off(const struct qm_sg_entry * sg)243*4882a593Smuzhiyun static inline int qm_sg_entry_get_off(const struct qm_sg_entry *sg)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	return be32_to_cpu(sg->offset) & QM_SG_OFF_MASK;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun /* "Frame Dequeue Response" */
249*4882a593Smuzhiyun struct qm_dqrr_entry {
250*4882a593Smuzhiyun 	u8 verb;
251*4882a593Smuzhiyun 	u8 stat;
252*4882a593Smuzhiyun 	__be16 seqnum;	/* 15-bit */
253*4882a593Smuzhiyun 	u8 tok;
254*4882a593Smuzhiyun 	u8 __reserved2[3];
255*4882a593Smuzhiyun 	__be32 fqid;	/* 24-bit */
256*4882a593Smuzhiyun 	__be32 context_b;
257*4882a593Smuzhiyun 	struct qm_fd fd;
258*4882a593Smuzhiyun 	u8 __reserved4[32];
259*4882a593Smuzhiyun } __packed __aligned(64);
260*4882a593Smuzhiyun #define QM_DQRR_VERB_VBIT		0x80
261*4882a593Smuzhiyun #define QM_DQRR_VERB_MASK		0x7f	/* where the verb contains; */
262*4882a593Smuzhiyun #define QM_DQRR_VERB_FRAME_DEQUEUE	0x60	/* "this format" */
263*4882a593Smuzhiyun #define QM_DQRR_STAT_FQ_EMPTY		0x80	/* FQ empty */
264*4882a593Smuzhiyun #define QM_DQRR_STAT_FQ_HELDACTIVE	0x40	/* FQ held active */
265*4882a593Smuzhiyun #define QM_DQRR_STAT_FQ_FORCEELIGIBLE	0x20	/* FQ was force-eligible'd */
266*4882a593Smuzhiyun #define QM_DQRR_STAT_FD_VALID		0x10	/* has a non-NULL FD */
267*4882a593Smuzhiyun #define QM_DQRR_STAT_UNSCHEDULED	0x02	/* Unscheduled dequeue */
268*4882a593Smuzhiyun #define QM_DQRR_STAT_DQCR_EXPIRED	0x01	/* VDQCR or PDQCR expired*/
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun /* 'fqid' is a 24-bit field in every h/w descriptor */
271*4882a593Smuzhiyun #define QM_FQID_MASK	GENMASK(23, 0)
272*4882a593Smuzhiyun #define qm_fqid_set(p, v) ((p)->fqid = cpu_to_be32((v) & QM_FQID_MASK))
273*4882a593Smuzhiyun #define qm_fqid_get(p)    (be32_to_cpu((p)->fqid) & QM_FQID_MASK)
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun /* "ERN Message Response" */
276*4882a593Smuzhiyun /* "FQ State Change Notification" */
277*4882a593Smuzhiyun union qm_mr_entry {
278*4882a593Smuzhiyun 	struct {
279*4882a593Smuzhiyun 		u8 verb;
280*4882a593Smuzhiyun 		u8 __reserved[63];
281*4882a593Smuzhiyun 	};
282*4882a593Smuzhiyun 	struct {
283*4882a593Smuzhiyun 		u8 verb;
284*4882a593Smuzhiyun 		u8 dca;
285*4882a593Smuzhiyun 		__be16 seqnum;
286*4882a593Smuzhiyun 		u8 rc;		/* Rej Code: 8-bit */
287*4882a593Smuzhiyun 		u8 __reserved[3];
288*4882a593Smuzhiyun 		__be32 fqid;	/* 24-bit */
289*4882a593Smuzhiyun 		__be32 tag;
290*4882a593Smuzhiyun 		struct qm_fd fd;
291*4882a593Smuzhiyun 		u8 __reserved1[32];
292*4882a593Smuzhiyun 	} __packed __aligned(64) ern;
293*4882a593Smuzhiyun 	struct {
294*4882a593Smuzhiyun 		u8 verb;
295*4882a593Smuzhiyun 		u8 fqs;		/* Frame Queue Status */
296*4882a593Smuzhiyun 		u8 __reserved1[6];
297*4882a593Smuzhiyun 		__be32 fqid;	/* 24-bit */
298*4882a593Smuzhiyun 		__be32 context_b;
299*4882a593Smuzhiyun 		u8 __reserved2[48];
300*4882a593Smuzhiyun 	} __packed fq;		/* FQRN/FQRNI/FQRL/FQPN */
301*4882a593Smuzhiyun };
302*4882a593Smuzhiyun #define QM_MR_VERB_VBIT			0x80
303*4882a593Smuzhiyun /*
304*4882a593Smuzhiyun  * ERNs originating from direct-connect portals ("dcern") use 0x20 as a verb
305*4882a593Smuzhiyun  * which would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished
306*4882a593Smuzhiyun  * from the other MR types by noting if the 0x20 bit is unset.
307*4882a593Smuzhiyun  */
308*4882a593Smuzhiyun #define QM_MR_VERB_TYPE_MASK		0x27
309*4882a593Smuzhiyun #define QM_MR_VERB_DC_ERN		0x20
310*4882a593Smuzhiyun #define QM_MR_VERB_FQRN			0x21
311*4882a593Smuzhiyun #define QM_MR_VERB_FQRNI		0x22
312*4882a593Smuzhiyun #define QM_MR_VERB_FQRL			0x23
313*4882a593Smuzhiyun #define QM_MR_VERB_FQPN			0x24
314*4882a593Smuzhiyun #define QM_MR_RC_MASK			0xf0	/* contains one of; */
315*4882a593Smuzhiyun #define QM_MR_RC_CGR_TAILDROP		0x00
316*4882a593Smuzhiyun #define QM_MR_RC_WRED			0x10
317*4882a593Smuzhiyun #define QM_MR_RC_ERROR			0x20
318*4882a593Smuzhiyun #define QM_MR_RC_ORPWINDOW_EARLY	0x30
319*4882a593Smuzhiyun #define QM_MR_RC_ORPWINDOW_LATE		0x40
320*4882a593Smuzhiyun #define QM_MR_RC_FQ_TAILDROP		0x50
321*4882a593Smuzhiyun #define QM_MR_RC_ORPWINDOW_RETIRED	0x60
322*4882a593Smuzhiyun #define QM_MR_RC_ORP_ZERO		0x70
323*4882a593Smuzhiyun #define QM_MR_FQS_ORLPRESENT		0x02	/* ORL fragments to come */
324*4882a593Smuzhiyun #define QM_MR_FQS_NOTEMPTY		0x01	/* FQ has enqueued frames */
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun /*
327*4882a593Smuzhiyun  * An identical structure of FQD fields is present in the "Init FQ" command and
328*4882a593Smuzhiyun  * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
329*4882a593Smuzhiyun  * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
330*4882a593Smuzhiyun  * latter has two inlines to assist with converting to/from the mant+exp
331*4882a593Smuzhiyun  * representation.
332*4882a593Smuzhiyun  */
333*4882a593Smuzhiyun struct qm_fqd_stashing {
334*4882a593Smuzhiyun 	/* See QM_STASHING_EXCL_<...> */
335*4882a593Smuzhiyun 	u8 exclusive;
336*4882a593Smuzhiyun 	/* Numbers of cachelines */
337*4882a593Smuzhiyun 	u8 cl; /* _res[6-7], as[4-5], ds[2-3], cs[0-1] */
338*4882a593Smuzhiyun };
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun struct qm_fqd_oac {
341*4882a593Smuzhiyun 	/* "Overhead Accounting Control", see QM_OAC_<...> */
342*4882a593Smuzhiyun 	u8 oac; /* oac[6-7], _res[0-5] */
343*4882a593Smuzhiyun 	/* Two's-complement value (-128 to +127) */
344*4882a593Smuzhiyun 	s8 oal; /* "Overhead Accounting Length" */
345*4882a593Smuzhiyun };
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun struct qm_fqd {
348*4882a593Smuzhiyun 	/* _res[6-7], orprws[3-5], oa[2], olws[0-1] */
349*4882a593Smuzhiyun 	u8 orpc;
350*4882a593Smuzhiyun 	u8 cgid;
351*4882a593Smuzhiyun 	__be16 fq_ctrl;	/* See QM_FQCTRL_<...> */
352*4882a593Smuzhiyun 	__be16 dest_wq;	/* channel[3-15], wq[0-2] */
353*4882a593Smuzhiyun 	__be16 ics_cred; /* 15-bit */
354*4882a593Smuzhiyun 	/*
355*4882a593Smuzhiyun 	 * For "Initialize Frame Queue" commands, the write-enable mask
356*4882a593Smuzhiyun 	 * determines whether 'td' or 'oac_init' is observed. For query
357*4882a593Smuzhiyun 	 * commands, this field is always 'td', and 'oac_query' (below) reflects
358*4882a593Smuzhiyun 	 * the Overhead ACcounting values.
359*4882a593Smuzhiyun 	 */
360*4882a593Smuzhiyun 	union {
361*4882a593Smuzhiyun 		__be16 td; /* "Taildrop": _res[13-15], mant[5-12], exp[0-4] */
362*4882a593Smuzhiyun 		struct qm_fqd_oac oac_init;
363*4882a593Smuzhiyun 	};
364*4882a593Smuzhiyun 	__be32 context_b;
365*4882a593Smuzhiyun 	union {
366*4882a593Smuzhiyun 		/* Treat it as 64-bit opaque */
367*4882a593Smuzhiyun 		__be64 opaque;
368*4882a593Smuzhiyun 		struct {
369*4882a593Smuzhiyun 			__be32 hi;
370*4882a593Smuzhiyun 			__be32 lo;
371*4882a593Smuzhiyun 		};
372*4882a593Smuzhiyun 		/* Treat it as s/w portal stashing config */
373*4882a593Smuzhiyun 		/* see "FQD Context_A field used for [...]" */
374*4882a593Smuzhiyun 		struct {
375*4882a593Smuzhiyun 			struct qm_fqd_stashing stashing;
376*4882a593Smuzhiyun 			/*
377*4882a593Smuzhiyun 			 * 48-bit address of FQ context to
378*4882a593Smuzhiyun 			 * stash, must be cacheline-aligned
379*4882a593Smuzhiyun 			 */
380*4882a593Smuzhiyun 			__be16 context_hi;
381*4882a593Smuzhiyun 			__be32 context_lo;
382*4882a593Smuzhiyun 		} __packed;
383*4882a593Smuzhiyun 	} context_a;
384*4882a593Smuzhiyun 	struct qm_fqd_oac oac_query;
385*4882a593Smuzhiyun } __packed;
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun #define QM_FQD_CHAN_OFF		3
388*4882a593Smuzhiyun #define QM_FQD_WQ_MASK		GENMASK(2, 0)
389*4882a593Smuzhiyun #define QM_FQD_TD_EXP_MASK	GENMASK(4, 0)
390*4882a593Smuzhiyun #define QM_FQD_TD_MANT_OFF	5
391*4882a593Smuzhiyun #define QM_FQD_TD_MANT_MASK	GENMASK(12, 5)
392*4882a593Smuzhiyun #define QM_FQD_TD_MAX		0xe0000000
393*4882a593Smuzhiyun #define QM_FQD_TD_MANT_MAX	0xff
394*4882a593Smuzhiyun #define QM_FQD_OAC_OFF		6
395*4882a593Smuzhiyun #define QM_FQD_AS_OFF		4
396*4882a593Smuzhiyun #define QM_FQD_DS_OFF		2
397*4882a593Smuzhiyun #define QM_FQD_XS_MASK		0x3
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun /* 64-bit converters for context_hi/lo */
qm_fqd_stashing_get64(const struct qm_fqd * fqd)400*4882a593Smuzhiyun static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun 	return be64_to_cpu(fqd->context_a.opaque) & 0xffffffffffffULL;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun 
qm_fqd_stashing_addr(const struct qm_fqd * fqd)405*4882a593Smuzhiyun static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun 	return be64_to_cpu(fqd->context_a.opaque) & 0xffffffffffffULL;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun 
qm_fqd_context_a_get64(const struct qm_fqd * fqd)410*4882a593Smuzhiyun static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun 	return qm_fqd_stashing_get64(fqd);
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun 
qm_fqd_stashing_set64(struct qm_fqd * fqd,u64 addr)415*4882a593Smuzhiyun static inline void qm_fqd_stashing_set64(struct qm_fqd *fqd, u64 addr)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun 	fqd->context_a.context_hi = cpu_to_be16(upper_32_bits(addr));
418*4882a593Smuzhiyun 	fqd->context_a.context_lo = cpu_to_be32(lower_32_bits(addr));
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun 
qm_fqd_context_a_set64(struct qm_fqd * fqd,u64 addr)421*4882a593Smuzhiyun static inline void qm_fqd_context_a_set64(struct qm_fqd *fqd, u64 addr)
422*4882a593Smuzhiyun {
423*4882a593Smuzhiyun 	fqd->context_a.hi = cpu_to_be32(upper_32_bits(addr));
424*4882a593Smuzhiyun 	fqd->context_a.lo = cpu_to_be32(lower_32_bits(addr));
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun /* convert a threshold value into mant+exp representation */
qm_fqd_set_taildrop(struct qm_fqd * fqd,u32 val,int roundup)428*4882a593Smuzhiyun static inline int qm_fqd_set_taildrop(struct qm_fqd *fqd, u32 val,
429*4882a593Smuzhiyun 				      int roundup)
430*4882a593Smuzhiyun {
431*4882a593Smuzhiyun 	u32 e = 0;
432*4882a593Smuzhiyun 	int td, oddbit = 0;
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	if (val > QM_FQD_TD_MAX)
435*4882a593Smuzhiyun 		return -ERANGE;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	while (val > QM_FQD_TD_MANT_MAX) {
438*4882a593Smuzhiyun 		oddbit = val & 1;
439*4882a593Smuzhiyun 		val >>= 1;
440*4882a593Smuzhiyun 		e++;
441*4882a593Smuzhiyun 		if (roundup && oddbit)
442*4882a593Smuzhiyun 			val++;
443*4882a593Smuzhiyun 	}
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	td = (val << QM_FQD_TD_MANT_OFF) & QM_FQD_TD_MANT_MASK;
446*4882a593Smuzhiyun 	td |= (e & QM_FQD_TD_EXP_MASK);
447*4882a593Smuzhiyun 	fqd->td = cpu_to_be16(td);
448*4882a593Smuzhiyun 	return 0;
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun /* and the other direction */
qm_fqd_get_taildrop(const struct qm_fqd * fqd)451*4882a593Smuzhiyun static inline int qm_fqd_get_taildrop(const struct qm_fqd *fqd)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun 	int td = be16_to_cpu(fqd->td);
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	return ((td & QM_FQD_TD_MANT_MASK) >> QM_FQD_TD_MANT_OFF)
456*4882a593Smuzhiyun 		<< (td & QM_FQD_TD_EXP_MASK);
457*4882a593Smuzhiyun }
458*4882a593Smuzhiyun 
qm_fqd_set_stashing(struct qm_fqd * fqd,u8 as,u8 ds,u8 cs)459*4882a593Smuzhiyun static inline void qm_fqd_set_stashing(struct qm_fqd *fqd, u8 as, u8 ds, u8 cs)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun 	struct qm_fqd_stashing *st = &fqd->context_a.stashing;
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	st->cl = ((as & QM_FQD_XS_MASK) << QM_FQD_AS_OFF) |
464*4882a593Smuzhiyun 		 ((ds & QM_FQD_XS_MASK) << QM_FQD_DS_OFF) |
465*4882a593Smuzhiyun 		 (cs & QM_FQD_XS_MASK);
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun 
qm_fqd_get_stashing(const struct qm_fqd * fqd)468*4882a593Smuzhiyun static inline u8 qm_fqd_get_stashing(const struct qm_fqd *fqd)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun 	return fqd->context_a.stashing.cl;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun 
qm_fqd_set_oac(struct qm_fqd * fqd,u8 val)473*4882a593Smuzhiyun static inline void qm_fqd_set_oac(struct qm_fqd *fqd, u8 val)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun 	fqd->oac_init.oac = val << QM_FQD_OAC_OFF;
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun 
qm_fqd_set_oal(struct qm_fqd * fqd,s8 val)478*4882a593Smuzhiyun static inline void qm_fqd_set_oal(struct qm_fqd *fqd, s8 val)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun 	fqd->oac_init.oal = val;
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun 
qm_fqd_set_destwq(struct qm_fqd * fqd,int ch,int wq)483*4882a593Smuzhiyun static inline void qm_fqd_set_destwq(struct qm_fqd *fqd, int ch, int wq)
484*4882a593Smuzhiyun {
485*4882a593Smuzhiyun 	fqd->dest_wq = cpu_to_be16((ch << QM_FQD_CHAN_OFF) |
486*4882a593Smuzhiyun 				   (wq & QM_FQD_WQ_MASK));
487*4882a593Smuzhiyun }
488*4882a593Smuzhiyun 
qm_fqd_get_chan(const struct qm_fqd * fqd)489*4882a593Smuzhiyun static inline int qm_fqd_get_chan(const struct qm_fqd *fqd)
490*4882a593Smuzhiyun {
491*4882a593Smuzhiyun 	return be16_to_cpu(fqd->dest_wq) >> QM_FQD_CHAN_OFF;
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun 
qm_fqd_get_wq(const struct qm_fqd * fqd)494*4882a593Smuzhiyun static inline int qm_fqd_get_wq(const struct qm_fqd *fqd)
495*4882a593Smuzhiyun {
496*4882a593Smuzhiyun 	return be16_to_cpu(fqd->dest_wq) & QM_FQD_WQ_MASK;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun /* See "Frame Queue Descriptor (FQD)" */
500*4882a593Smuzhiyun /* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
501*4882a593Smuzhiyun #define QM_FQCTRL_MASK		0x07ff	/* 'fq_ctrl' flags; */
502*4882a593Smuzhiyun #define QM_FQCTRL_CGE		0x0400	/* Congestion Group Enable */
503*4882a593Smuzhiyun #define QM_FQCTRL_TDE		0x0200	/* Tail-Drop Enable */
504*4882a593Smuzhiyun #define QM_FQCTRL_CTXASTASHING	0x0080	/* Context-A stashing */
505*4882a593Smuzhiyun #define QM_FQCTRL_CPCSTASH	0x0040	/* CPC Stash Enable */
506*4882a593Smuzhiyun #define QM_FQCTRL_FORCESFDR	0x0008	/* High-priority SFDRs */
507*4882a593Smuzhiyun #define QM_FQCTRL_AVOIDBLOCK	0x0004	/* Don't block active */
508*4882a593Smuzhiyun #define QM_FQCTRL_HOLDACTIVE	0x0002	/* Hold active in portal */
509*4882a593Smuzhiyun #define QM_FQCTRL_PREFERINCACHE	0x0001	/* Aggressively cache FQD */
510*4882a593Smuzhiyun #define QM_FQCTRL_LOCKINCACHE	QM_FQCTRL_PREFERINCACHE /* older naming */
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun /* See "FQD Context_A field used for [...] */
513*4882a593Smuzhiyun /* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
514*4882a593Smuzhiyun #define QM_STASHING_EXCL_ANNOTATION	0x04
515*4882a593Smuzhiyun #define QM_STASHING_EXCL_DATA		0x02
516*4882a593Smuzhiyun #define QM_STASHING_EXCL_CTX		0x01
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun /* See "Intra Class Scheduling" */
519*4882a593Smuzhiyun /* FQD field 'OAC' (Overhead ACcounting) uses these constants */
520*4882a593Smuzhiyun #define QM_OAC_ICS		0x2 /* Accounting for Intra-Class Scheduling */
521*4882a593Smuzhiyun #define QM_OAC_CG		0x1 /* Accounting for Congestion Groups */
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun /*
524*4882a593Smuzhiyun  * This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
525*4882a593Smuzhiyun  * and associated commands/responses. The WRED parameters are calculated from
526*4882a593Smuzhiyun  * these fields as follows;
527*4882a593Smuzhiyun  *   MaxTH = MA * (2 ^ Mn)
528*4882a593Smuzhiyun  *   Slope = SA / (2 ^ Sn)
529*4882a593Smuzhiyun  *    MaxP = 4 * (Pn + 1)
530*4882a593Smuzhiyun  */
531*4882a593Smuzhiyun struct qm_cgr_wr_parm {
532*4882a593Smuzhiyun 	/* MA[24-31], Mn[19-23], SA[12-18], Sn[6-11], Pn[0-5] */
533*4882a593Smuzhiyun 	__be32 word;
534*4882a593Smuzhiyun };
535*4882a593Smuzhiyun /*
536*4882a593Smuzhiyun  * This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
537*4882a593Smuzhiyun  * management commands, this is padded to a 16-bit structure field, so that's
538*4882a593Smuzhiyun  * how we represent it here. The congestion state threshold is calculated from
539*4882a593Smuzhiyun  * these fields as follows;
540*4882a593Smuzhiyun  *   CS threshold = TA * (2 ^ Tn)
541*4882a593Smuzhiyun  */
542*4882a593Smuzhiyun struct qm_cgr_cs_thres {
543*4882a593Smuzhiyun 	/* _res[13-15], TA[5-12], Tn[0-4] */
544*4882a593Smuzhiyun 	__be16 word;
545*4882a593Smuzhiyun };
546*4882a593Smuzhiyun /*
547*4882a593Smuzhiyun  * This identical structure of CGR fields is present in the "Init/Modify CGR"
548*4882a593Smuzhiyun  * commands and the "Query CGR" result. It's suctioned out here into its own
549*4882a593Smuzhiyun  * struct.
550*4882a593Smuzhiyun  */
551*4882a593Smuzhiyun struct __qm_mc_cgr {
552*4882a593Smuzhiyun 	struct qm_cgr_wr_parm wr_parm_g;
553*4882a593Smuzhiyun 	struct qm_cgr_wr_parm wr_parm_y;
554*4882a593Smuzhiyun 	struct qm_cgr_wr_parm wr_parm_r;
555*4882a593Smuzhiyun 	u8 wr_en_g;	/* boolean, use QM_CGR_EN */
556*4882a593Smuzhiyun 	u8 wr_en_y;	/* boolean, use QM_CGR_EN */
557*4882a593Smuzhiyun 	u8 wr_en_r;	/* boolean, use QM_CGR_EN */
558*4882a593Smuzhiyun 	u8 cscn_en;	/* boolean, use QM_CGR_EN */
559*4882a593Smuzhiyun 	union {
560*4882a593Smuzhiyun 		struct {
561*4882a593Smuzhiyun 			__be16 cscn_targ_upd_ctrl; /* use QM_CGR_TARG_UDP_* */
562*4882a593Smuzhiyun 			__be16 cscn_targ_dcp_low;
563*4882a593Smuzhiyun 		};
564*4882a593Smuzhiyun 		__be32 cscn_targ;	/* use QM_CGR_TARG_* */
565*4882a593Smuzhiyun 	};
566*4882a593Smuzhiyun 	u8 cstd_en;	/* boolean, use QM_CGR_EN */
567*4882a593Smuzhiyun 	u8 cs;		/* boolean, only used in query response */
568*4882a593Smuzhiyun 	struct qm_cgr_cs_thres cs_thres; /* use qm_cgr_cs_thres_set64() */
569*4882a593Smuzhiyun 	u8 mode;	/* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
570*4882a593Smuzhiyun } __packed;
571*4882a593Smuzhiyun #define QM_CGR_EN		0x01 /* For wr_en_*, cscn_en, cstd_en */
572*4882a593Smuzhiyun #define QM_CGR_TARG_UDP_CTRL_WRITE_BIT	0x8000 /* value written to portal bit*/
573*4882a593Smuzhiyun #define QM_CGR_TARG_UDP_CTRL_DCP	0x4000 /* 0: SWP, 1: DCP */
574*4882a593Smuzhiyun #define QM_CGR_TARG_PORTAL(n)	(0x80000000 >> (n)) /* s/w portal, 0-9 */
575*4882a593Smuzhiyun #define QM_CGR_TARG_FMAN0	0x00200000 /* direct-connect portal: fman0 */
576*4882a593Smuzhiyun #define QM_CGR_TARG_FMAN1	0x00100000 /*			   : fman1 */
577*4882a593Smuzhiyun /* Convert CGR thresholds to/from "cs_thres" format */
qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres * th)578*4882a593Smuzhiyun static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun 	int thres = be16_to_cpu(th->word);
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	return ((thres >> 5) & 0xff) << (thres & 0x1f);
583*4882a593Smuzhiyun }
584*4882a593Smuzhiyun 
qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres * th,u64 val,int roundup)585*4882a593Smuzhiyun static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
586*4882a593Smuzhiyun 					int roundup)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun 	u32 e = 0;
589*4882a593Smuzhiyun 	int oddbit = 0;
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	while (val > 0xff) {
592*4882a593Smuzhiyun 		oddbit = val & 1;
593*4882a593Smuzhiyun 		val >>= 1;
594*4882a593Smuzhiyun 		e++;
595*4882a593Smuzhiyun 		if (roundup && oddbit)
596*4882a593Smuzhiyun 			val++;
597*4882a593Smuzhiyun 	}
598*4882a593Smuzhiyun 	th->word = cpu_to_be16(((val & 0xff) << 5) | (e & 0x1f));
599*4882a593Smuzhiyun 	return 0;
600*4882a593Smuzhiyun }
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun /* "Initialize FQ" */
603*4882a593Smuzhiyun struct qm_mcc_initfq {
604*4882a593Smuzhiyun 	u8 __reserved1[2];
605*4882a593Smuzhiyun 	__be16 we_mask;	/* Write Enable Mask */
606*4882a593Smuzhiyun 	__be32 fqid;	/* 24-bit */
607*4882a593Smuzhiyun 	__be16 count;	/* Initialises 'count+1' FQDs */
608*4882a593Smuzhiyun 	struct qm_fqd fqd; /* the FQD fields go here */
609*4882a593Smuzhiyun 	u8 __reserved2[30];
610*4882a593Smuzhiyun } __packed;
611*4882a593Smuzhiyun /* "Initialize/Modify CGR" */
612*4882a593Smuzhiyun struct qm_mcc_initcgr {
613*4882a593Smuzhiyun 	u8 __reserve1[2];
614*4882a593Smuzhiyun 	__be16 we_mask;	/* Write Enable Mask */
615*4882a593Smuzhiyun 	struct __qm_mc_cgr cgr;	/* CGR fields */
616*4882a593Smuzhiyun 	u8 __reserved2[2];
617*4882a593Smuzhiyun 	u8 cgid;
618*4882a593Smuzhiyun 	u8 __reserved3[32];
619*4882a593Smuzhiyun } __packed;
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun /* INITFQ-specific flags */
622*4882a593Smuzhiyun #define QM_INITFQ_WE_MASK		0x01ff	/* 'Write Enable' flags; */
623*4882a593Smuzhiyun #define QM_INITFQ_WE_OAC		0x0100
624*4882a593Smuzhiyun #define QM_INITFQ_WE_ORPC		0x0080
625*4882a593Smuzhiyun #define QM_INITFQ_WE_CGID		0x0040
626*4882a593Smuzhiyun #define QM_INITFQ_WE_FQCTRL		0x0020
627*4882a593Smuzhiyun #define QM_INITFQ_WE_DESTWQ		0x0010
628*4882a593Smuzhiyun #define QM_INITFQ_WE_ICSCRED		0x0008
629*4882a593Smuzhiyun #define QM_INITFQ_WE_TDTHRESH		0x0004
630*4882a593Smuzhiyun #define QM_INITFQ_WE_CONTEXTB		0x0002
631*4882a593Smuzhiyun #define QM_INITFQ_WE_CONTEXTA		0x0001
632*4882a593Smuzhiyun /* INITCGR/MODIFYCGR-specific flags */
633*4882a593Smuzhiyun #define QM_CGR_WE_MASK			0x07ff	/* 'Write Enable Mask'; */
634*4882a593Smuzhiyun #define QM_CGR_WE_WR_PARM_G		0x0400
635*4882a593Smuzhiyun #define QM_CGR_WE_WR_PARM_Y		0x0200
636*4882a593Smuzhiyun #define QM_CGR_WE_WR_PARM_R		0x0100
637*4882a593Smuzhiyun #define QM_CGR_WE_WR_EN_G		0x0080
638*4882a593Smuzhiyun #define QM_CGR_WE_WR_EN_Y		0x0040
639*4882a593Smuzhiyun #define QM_CGR_WE_WR_EN_R		0x0020
640*4882a593Smuzhiyun #define QM_CGR_WE_CSCN_EN		0x0010
641*4882a593Smuzhiyun #define QM_CGR_WE_CSCN_TARG		0x0008
642*4882a593Smuzhiyun #define QM_CGR_WE_CSTD_EN		0x0004
643*4882a593Smuzhiyun #define QM_CGR_WE_CS_THRES		0x0002
644*4882a593Smuzhiyun #define QM_CGR_WE_MODE			0x0001
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun #define QMAN_CGR_FLAG_USE_INIT	     0x00000001
647*4882a593Smuzhiyun #define QMAN_CGR_MODE_FRAME          0x00000001
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 	/* Portal and Frame Queues */
650*4882a593Smuzhiyun /* Represents a managed portal */
651*4882a593Smuzhiyun struct qman_portal;
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun /*
654*4882a593Smuzhiyun  * This object type represents QMan frame queue descriptors (FQD), it is
655*4882a593Smuzhiyun  * cacheline-aligned, and initialised by qman_create_fq(). The structure is
656*4882a593Smuzhiyun  * defined further down.
657*4882a593Smuzhiyun  */
658*4882a593Smuzhiyun struct qman_fq;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun /*
661*4882a593Smuzhiyun  * This object type represents a QMan congestion group, it is defined further
662*4882a593Smuzhiyun  * down.
663*4882a593Smuzhiyun  */
664*4882a593Smuzhiyun struct qman_cgr;
665*4882a593Smuzhiyun 
666*4882a593Smuzhiyun /*
667*4882a593Smuzhiyun  * This enum, and the callback type that returns it, are used when handling
668*4882a593Smuzhiyun  * dequeued frames via DQRR. Note that for "null" callbacks registered with the
669*4882a593Smuzhiyun  * portal object (for handling dequeues that do not demux because context_b is
670*4882a593Smuzhiyun  * NULL), the return value *MUST* be qman_cb_dqrr_consume.
671*4882a593Smuzhiyun  */
672*4882a593Smuzhiyun enum qman_cb_dqrr_result {
673*4882a593Smuzhiyun 	/* DQRR entry can be consumed */
674*4882a593Smuzhiyun 	qman_cb_dqrr_consume,
675*4882a593Smuzhiyun 	/* Like _consume, but requests parking - FQ must be held-active */
676*4882a593Smuzhiyun 	qman_cb_dqrr_park,
677*4882a593Smuzhiyun 	/* Does not consume, for DCA mode only. */
678*4882a593Smuzhiyun 	qman_cb_dqrr_defer,
679*4882a593Smuzhiyun 	/*
680*4882a593Smuzhiyun 	 * Stop processing without consuming this ring entry. Exits the current
681*4882a593Smuzhiyun 	 * qman_p_poll_dqrr() or interrupt-handling, as appropriate. If within
682*4882a593Smuzhiyun 	 * an interrupt handler, the callback would typically call
683*4882a593Smuzhiyun 	 * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
684*4882a593Smuzhiyun 	 * otherwise the interrupt will reassert immediately.
685*4882a593Smuzhiyun 	 */
686*4882a593Smuzhiyun 	qman_cb_dqrr_stop,
687*4882a593Smuzhiyun 	/* Like qman_cb_dqrr_stop, but consumes the current entry. */
688*4882a593Smuzhiyun 	qman_cb_dqrr_consume_stop
689*4882a593Smuzhiyun };
690*4882a593Smuzhiyun typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
691*4882a593Smuzhiyun 					struct qman_fq *fq,
692*4882a593Smuzhiyun 					const struct qm_dqrr_entry *dqrr);
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun /*
695*4882a593Smuzhiyun  * This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
696*4882a593Smuzhiyun  * are always consumed after the callback returns.
697*4882a593Smuzhiyun  */
698*4882a593Smuzhiyun typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
699*4882a593Smuzhiyun 			   const union qm_mr_entry *msg);
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun /*
702*4882a593Smuzhiyun  * s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
703*4882a593Smuzhiyun  * held-active + held-suspended are just "sched". Things like "retired" will not
704*4882a593Smuzhiyun  * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
705*4882a593Smuzhiyun  * then, to indicate it's completing and to gate attempts to retry the retire
706*4882a593Smuzhiyun  * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
707*4882a593Smuzhiyun  * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
708*4882a593Smuzhiyun  * index rather than the FQ that ring entry corresponds to), so repeated park
709*4882a593Smuzhiyun  * commands are allowed (if you're silly enough to try) but won't change FQ
710*4882a593Smuzhiyun  * state, and the resulting park notifications move FQs from "sched" to
711*4882a593Smuzhiyun  * "parked".
712*4882a593Smuzhiyun  */
713*4882a593Smuzhiyun enum qman_fq_state {
714*4882a593Smuzhiyun 	qman_fq_state_oos,
715*4882a593Smuzhiyun 	qman_fq_state_parked,
716*4882a593Smuzhiyun 	qman_fq_state_sched,
717*4882a593Smuzhiyun 	qman_fq_state_retired
718*4882a593Smuzhiyun };
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun #define QMAN_FQ_STATE_CHANGING	     0x80000000 /* 'state' is changing */
721*4882a593Smuzhiyun #define QMAN_FQ_STATE_NE	     0x40000000 /* retired FQ isn't empty */
722*4882a593Smuzhiyun #define QMAN_FQ_STATE_ORL	     0x20000000 /* retired FQ has ORL */
723*4882a593Smuzhiyun #define QMAN_FQ_STATE_BLOCKOOS	     0xe0000000 /* if any are set, no OOS */
724*4882a593Smuzhiyun #define QMAN_FQ_STATE_CGR_EN	     0x10000000 /* CGR enabled */
725*4882a593Smuzhiyun #define QMAN_FQ_STATE_VDQCR	     0x08000000 /* being volatile dequeued */
726*4882a593Smuzhiyun 
727*4882a593Smuzhiyun /*
728*4882a593Smuzhiyun  * Frame queue objects (struct qman_fq) are stored within memory passed to
729*4882a593Smuzhiyun  * qman_create_fq(), as this allows stashing of caller-provided demux callback
730*4882a593Smuzhiyun  * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
731*4882a593Smuzhiyun  * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
732*4882a593Smuzhiyun  * they should;
733*4882a593Smuzhiyun  *
734*4882a593Smuzhiyun  * (a) extend the qman_fq structure with their state; eg.
735*4882a593Smuzhiyun  *
736*4882a593Smuzhiyun  *     // myfq is allocated and driver_fq callbacks filled in;
737*4882a593Smuzhiyun  *     struct my_fq {
738*4882a593Smuzhiyun  *	   struct qman_fq base;
739*4882a593Smuzhiyun  *	   int an_extra_field;
740*4882a593Smuzhiyun  *	   [ ... add other fields to be associated with each FQ ...]
741*4882a593Smuzhiyun  *     } *myfq = some_my_fq_allocator();
742*4882a593Smuzhiyun  *     struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
743*4882a593Smuzhiyun  *
744*4882a593Smuzhiyun  *     // in a dequeue callback, access extra fields from 'fq' via a cast;
745*4882a593Smuzhiyun  *     struct my_fq *myfq = (struct my_fq *)fq;
746*4882a593Smuzhiyun  *     do_something_with(myfq->an_extra_field);
747*4882a593Smuzhiyun  *     [...]
748*4882a593Smuzhiyun  *
749*4882a593Smuzhiyun  * (b) when and if configuring the FQ for context stashing, specify how ever
750*4882a593Smuzhiyun  *     many cachelines are required to stash 'struct my_fq', to accelerate not
751*4882a593Smuzhiyun  *     only the QMan driver but the callback as well.
752*4882a593Smuzhiyun  */
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun struct qman_fq_cb {
755*4882a593Smuzhiyun 	qman_cb_dqrr dqrr;	/* for dequeued frames */
756*4882a593Smuzhiyun 	qman_cb_mr ern;		/* for s/w ERNs */
757*4882a593Smuzhiyun 	qman_cb_mr fqs;		/* frame-queue state changes*/
758*4882a593Smuzhiyun };
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun struct qman_fq {
761*4882a593Smuzhiyun 	/* Caller of qman_create_fq() provides these demux callbacks */
762*4882a593Smuzhiyun 	struct qman_fq_cb cb;
763*4882a593Smuzhiyun 	/*
764*4882a593Smuzhiyun 	 * These are internal to the driver, don't touch. In particular, they
765*4882a593Smuzhiyun 	 * may change, be removed, or extended (so you shouldn't rely on
766*4882a593Smuzhiyun 	 * sizeof(qman_fq) being a constant).
767*4882a593Smuzhiyun 	 */
768*4882a593Smuzhiyun 	u32 fqid, idx;
769*4882a593Smuzhiyun 	unsigned long flags;
770*4882a593Smuzhiyun 	enum qman_fq_state state;
771*4882a593Smuzhiyun 	int cgr_groupid;
772*4882a593Smuzhiyun };
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun /*
775*4882a593Smuzhiyun  * This callback type is used when handling congestion group entry/exit.
776*4882a593Smuzhiyun  * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
777*4882a593Smuzhiyun  */
778*4882a593Smuzhiyun typedef void (*qman_cb_cgr)(struct qman_portal *qm,
779*4882a593Smuzhiyun 			    struct qman_cgr *cgr, int congested);
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun struct qman_cgr {
782*4882a593Smuzhiyun 	/* Set these prior to qman_create_cgr() */
783*4882a593Smuzhiyun 	u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
784*4882a593Smuzhiyun 	qman_cb_cgr cb;
785*4882a593Smuzhiyun 	/* These are private to the driver */
786*4882a593Smuzhiyun 	u16 chan; /* portal channel this object is created on */
787*4882a593Smuzhiyun 	struct list_head node;
788*4882a593Smuzhiyun };
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun /* Flags to qman_create_fq() */
791*4882a593Smuzhiyun #define QMAN_FQ_FLAG_NO_ENQUEUE	     0x00000001 /* can't enqueue */
792*4882a593Smuzhiyun #define QMAN_FQ_FLAG_NO_MODIFY	     0x00000002 /* can only enqueue */
793*4882a593Smuzhiyun #define QMAN_FQ_FLAG_TO_DCPORTAL     0x00000004 /* consumed by CAAM/PME/Fman */
794*4882a593Smuzhiyun #define QMAN_FQ_FLAG_DYNAMIC_FQID    0x00000020 /* (de)allocate fqid */
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun /* Flags to qman_init_fq() */
797*4882a593Smuzhiyun #define QMAN_INITFQ_FLAG_SCHED	     0x00000001 /* schedule rather than park */
798*4882a593Smuzhiyun #define QMAN_INITFQ_FLAG_LOCAL	     0x00000004 /* set dest portal */
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun /*
801*4882a593Smuzhiyun  * For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
802*4882a593Smuzhiyun  * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
803*4882a593Smuzhiyun  * FQID(n) to fill in the frame queue ID.
804*4882a593Smuzhiyun  */
805*4882a593Smuzhiyun #define QM_VDQCR_PRECEDENCE_VDQCR	0x0
806*4882a593Smuzhiyun #define QM_VDQCR_PRECEDENCE_SDQCR	0x80000000
807*4882a593Smuzhiyun #define QM_VDQCR_EXACT			0x40000000
808*4882a593Smuzhiyun #define QM_VDQCR_NUMFRAMES_MASK		0x3f000000
809*4882a593Smuzhiyun #define QM_VDQCR_NUMFRAMES_SET(n)	(((n) & 0x3f) << 24)
810*4882a593Smuzhiyun #define QM_VDQCR_NUMFRAMES_GET(n)	(((n) >> 24) & 0x3f)
811*4882a593Smuzhiyun #define QM_VDQCR_NUMFRAMES_TILLEMPTY	QM_VDQCR_NUMFRAMES_SET(0)
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun #define QMAN_VOLATILE_FLAG_WAIT	     0x00000001 /* wait if VDQCR is in use */
814*4882a593Smuzhiyun #define QMAN_VOLATILE_FLAG_WAIT_INT  0x00000002 /* if wait, interruptible? */
815*4882a593Smuzhiyun #define QMAN_VOLATILE_FLAG_FINISH    0x00000004 /* wait till VDQCR completes */
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun /* "Query FQ Non-Programmable Fields" */
818*4882a593Smuzhiyun struct qm_mcr_queryfq_np {
819*4882a593Smuzhiyun 	u8 verb;
820*4882a593Smuzhiyun 	u8 result;
821*4882a593Smuzhiyun 	u8 __reserved1;
822*4882a593Smuzhiyun 	u8 state;		/* QM_MCR_NP_STATE_*** */
823*4882a593Smuzhiyun 	u32 fqd_link;		/* 24-bit, _res2[24-31] */
824*4882a593Smuzhiyun 	u16 odp_seq;		/* 14-bit, _res3[14-15] */
825*4882a593Smuzhiyun 	u16 orp_nesn;		/* 14-bit, _res4[14-15] */
826*4882a593Smuzhiyun 	u16 orp_ea_hseq;	/* 15-bit, _res5[15] */
827*4882a593Smuzhiyun 	u16 orp_ea_tseq;	/* 15-bit, _res6[15] */
828*4882a593Smuzhiyun 	u32 orp_ea_hptr;	/* 24-bit, _res7[24-31] */
829*4882a593Smuzhiyun 	u32 orp_ea_tptr;	/* 24-bit, _res8[24-31] */
830*4882a593Smuzhiyun 	u32 pfdr_hptr;		/* 24-bit, _res9[24-31] */
831*4882a593Smuzhiyun 	u32 pfdr_tptr;		/* 24-bit, _res10[24-31] */
832*4882a593Smuzhiyun 	u8 __reserved2[5];
833*4882a593Smuzhiyun 	u8 is;			/* 1-bit, _res12[1-7] */
834*4882a593Smuzhiyun 	u16 ics_surp;
835*4882a593Smuzhiyun 	u32 byte_cnt;
836*4882a593Smuzhiyun 	u32 frm_cnt;		/* 24-bit, _res13[24-31] */
837*4882a593Smuzhiyun 	u32 __reserved3;
838*4882a593Smuzhiyun 	u16 ra1_sfdr;		/* QM_MCR_NP_RA1_*** */
839*4882a593Smuzhiyun 	u16 ra2_sfdr;		/* QM_MCR_NP_RA2_*** */
840*4882a593Smuzhiyun 	u16 __reserved4;
841*4882a593Smuzhiyun 	u16 od1_sfdr;		/* QM_MCR_NP_OD1_*** */
842*4882a593Smuzhiyun 	u16 od2_sfdr;		/* QM_MCR_NP_OD2_*** */
843*4882a593Smuzhiyun 	u16 od3_sfdr;		/* QM_MCR_NP_OD3_*** */
844*4882a593Smuzhiyun } __packed;
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun #define QM_MCR_NP_STATE_FE		0x10
847*4882a593Smuzhiyun #define QM_MCR_NP_STATE_R		0x08
848*4882a593Smuzhiyun #define QM_MCR_NP_STATE_MASK		0x07	/* Reads FQD::STATE; */
849*4882a593Smuzhiyun #define QM_MCR_NP_STATE_OOS		0x00
850*4882a593Smuzhiyun #define QM_MCR_NP_STATE_RETIRED		0x01
851*4882a593Smuzhiyun #define QM_MCR_NP_STATE_TEN_SCHED	0x02
852*4882a593Smuzhiyun #define QM_MCR_NP_STATE_TRU_SCHED	0x03
853*4882a593Smuzhiyun #define QM_MCR_NP_STATE_PARKED		0x04
854*4882a593Smuzhiyun #define QM_MCR_NP_STATE_ACTIVE		0x05
855*4882a593Smuzhiyun #define QM_MCR_NP_PTR_MASK		0x07ff	/* for RA[12] & OD[123] */
856*4882a593Smuzhiyun #define QM_MCR_NP_RA1_NRA(v)		(((v) >> 14) & 0x3)	/* FQD::NRA */
857*4882a593Smuzhiyun #define QM_MCR_NP_RA2_IT(v)		(((v) >> 14) & 0x1)	/* FQD::IT */
858*4882a593Smuzhiyun #define QM_MCR_NP_OD1_NOD(v)		(((v) >> 14) & 0x3)	/* FQD::NOD */
859*4882a593Smuzhiyun #define QM_MCR_NP_OD3_NPC(v)		(((v) >> 14) & 0x3)	/* FQD::NPC */
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun enum qm_mcr_queryfq_np_masks {
862*4882a593Smuzhiyun 	qm_mcr_fqd_link_mask = BIT(24) - 1,
863*4882a593Smuzhiyun 	qm_mcr_odp_seq_mask = BIT(14) - 1,
864*4882a593Smuzhiyun 	qm_mcr_orp_nesn_mask = BIT(14) - 1,
865*4882a593Smuzhiyun 	qm_mcr_orp_ea_hseq_mask = BIT(15) - 1,
866*4882a593Smuzhiyun 	qm_mcr_orp_ea_tseq_mask = BIT(15) - 1,
867*4882a593Smuzhiyun 	qm_mcr_orp_ea_hptr_mask = BIT(24) - 1,
868*4882a593Smuzhiyun 	qm_mcr_orp_ea_tptr_mask = BIT(24) - 1,
869*4882a593Smuzhiyun 	qm_mcr_pfdr_hptr_mask = BIT(24) - 1,
870*4882a593Smuzhiyun 	qm_mcr_pfdr_tptr_mask = BIT(24) - 1,
871*4882a593Smuzhiyun 	qm_mcr_is_mask = BIT(1) - 1,
872*4882a593Smuzhiyun 	qm_mcr_frm_cnt_mask = BIT(24) - 1,
873*4882a593Smuzhiyun };
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun #define qm_mcr_np_get(np, field) \
876*4882a593Smuzhiyun 	((np)->field & (qm_mcr_##field##_mask))
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun 	/* Portal Management */
879*4882a593Smuzhiyun /**
880*4882a593Smuzhiyun  * qman_p_irqsource_add - add processing sources to be interrupt-driven
881*4882a593Smuzhiyun  * @bits: bitmask of QM_PIRQ_**I processing sources
882*4882a593Smuzhiyun  *
883*4882a593Smuzhiyun  * Adds processing sources that should be interrupt-driven (rather than
884*4882a593Smuzhiyun  * processed via qman_poll_***() functions).
885*4882a593Smuzhiyun  */
886*4882a593Smuzhiyun void qman_p_irqsource_add(struct qman_portal *p, u32 bits);
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun /**
889*4882a593Smuzhiyun  * qman_p_irqsource_remove - remove processing sources from being int-driven
890*4882a593Smuzhiyun  * @bits: bitmask of QM_PIRQ_**I processing sources
891*4882a593Smuzhiyun  *
892*4882a593Smuzhiyun  * Removes processing sources from being interrupt-driven, so that they will
893*4882a593Smuzhiyun  * instead be processed via qman_poll_***() functions.
894*4882a593Smuzhiyun  */
895*4882a593Smuzhiyun void qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun /**
898*4882a593Smuzhiyun  * qman_affine_cpus - return a mask of cpus that have affine portals
899*4882a593Smuzhiyun  */
900*4882a593Smuzhiyun const cpumask_t *qman_affine_cpus(void);
901*4882a593Smuzhiyun 
902*4882a593Smuzhiyun /**
903*4882a593Smuzhiyun  * qman_affine_channel - return the channel ID of an portal
904*4882a593Smuzhiyun  * @cpu: the cpu whose affine portal is the subject of the query
905*4882a593Smuzhiyun  *
906*4882a593Smuzhiyun  * If @cpu is -1, the affine portal for the current CPU will be used. It is a
907*4882a593Smuzhiyun  * bug to call this function for any value of @cpu (other than -1) that is not a
908*4882a593Smuzhiyun  * member of the mask returned from qman_affine_cpus().
909*4882a593Smuzhiyun  */
910*4882a593Smuzhiyun u16 qman_affine_channel(int cpu);
911*4882a593Smuzhiyun 
912*4882a593Smuzhiyun /**
913*4882a593Smuzhiyun  * qman_get_affine_portal - return the portal pointer affine to cpu
914*4882a593Smuzhiyun  * @cpu: the cpu whose affine portal is the subject of the query
915*4882a593Smuzhiyun  */
916*4882a593Smuzhiyun struct qman_portal *qman_get_affine_portal(int cpu);
917*4882a593Smuzhiyun 
918*4882a593Smuzhiyun /**
919*4882a593Smuzhiyun  * qman_start_using_portal - register a device link for the portal user
920*4882a593Smuzhiyun  * @p: the portal that will be in use
921*4882a593Smuzhiyun  * @dev: the device that will use the portal
922*4882a593Smuzhiyun  *
923*4882a593Smuzhiyun  * Makes sure that the devices that use the portal are unbound when the
924*4882a593Smuzhiyun  * portal is unbound
925*4882a593Smuzhiyun  */
926*4882a593Smuzhiyun int qman_start_using_portal(struct qman_portal *p, struct device *dev);
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun /**
929*4882a593Smuzhiyun  * qman_p_poll_dqrr - process DQRR (fast-path) entries
930*4882a593Smuzhiyun  * @limit: the maximum number of DQRR entries to process
931*4882a593Smuzhiyun  *
932*4882a593Smuzhiyun  * Use of this function requires that DQRR processing not be interrupt-driven.
933*4882a593Smuzhiyun  * The return value represents the number of DQRR entries processed.
934*4882a593Smuzhiyun  */
935*4882a593Smuzhiyun int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun /**
938*4882a593Smuzhiyun  * qman_p_static_dequeue_add - Add pool channels to the portal SDQCR
939*4882a593Smuzhiyun  * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
940*4882a593Smuzhiyun  *
941*4882a593Smuzhiyun  * Adds a set of pool channels to the portal's static dequeue command register
942*4882a593Smuzhiyun  * (SDQCR). The requested pools are limited to those the portal has dequeue
943*4882a593Smuzhiyun  * access to.
944*4882a593Smuzhiyun  */
945*4882a593Smuzhiyun void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
946*4882a593Smuzhiyun 
947*4882a593Smuzhiyun 	/* FQ management */
948*4882a593Smuzhiyun /**
949*4882a593Smuzhiyun  * qman_create_fq - Allocates a FQ
950*4882a593Smuzhiyun  * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
951*4882a593Smuzhiyun  * @flags: bit-mask of QMAN_FQ_FLAG_*** options
952*4882a593Smuzhiyun  * @fq: memory for storing the 'fq', with callbacks filled in
953*4882a593Smuzhiyun  *
954*4882a593Smuzhiyun  * Creates a frame queue object for the given @fqid, unless the
955*4882a593Smuzhiyun  * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
956*4882a593Smuzhiyun  * dynamically allocated (or the function fails if none are available). Once
957*4882a593Smuzhiyun  * created, the caller should not touch the memory at 'fq' except as extended to
958*4882a593Smuzhiyun  * adjacent memory for user-defined fields (see the definition of "struct
959*4882a593Smuzhiyun  * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
960*4882a593Smuzhiyun  * pre-existing frame-queues that aren't to be otherwise interfered with, it
961*4882a593Smuzhiyun  * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
962*4882a593Smuzhiyun  * causes the driver to honour any context_b modifications requested in the
963*4882a593Smuzhiyun  * qm_init_fq() API, as this indicates the frame queue will be consumed by a
964*4882a593Smuzhiyun  * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
965*4882a593Smuzhiyun  * software portals, the context_b field is controlled by the driver and can't
966*4882a593Smuzhiyun  * be modified by the caller.
967*4882a593Smuzhiyun  */
968*4882a593Smuzhiyun int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun /**
971*4882a593Smuzhiyun  * qman_destroy_fq - Deallocates a FQ
972*4882a593Smuzhiyun  * @fq: the frame queue object to release
973*4882a593Smuzhiyun  *
974*4882a593Smuzhiyun  * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
975*4882a593Smuzhiyun  * not deallocated but the caller regains ownership, to do with as desired. The
976*4882a593Smuzhiyun  * FQ must be in the 'out-of-service' or in the 'parked' state.
977*4882a593Smuzhiyun  */
978*4882a593Smuzhiyun void qman_destroy_fq(struct qman_fq *fq);
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun /**
981*4882a593Smuzhiyun  * qman_fq_fqid - Queries the frame queue ID of a FQ object
982*4882a593Smuzhiyun  * @fq: the frame queue object to query
983*4882a593Smuzhiyun  */
984*4882a593Smuzhiyun u32 qman_fq_fqid(struct qman_fq *fq);
985*4882a593Smuzhiyun 
986*4882a593Smuzhiyun /**
987*4882a593Smuzhiyun  * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
988*4882a593Smuzhiyun  * @fq: the frame queue object to modify, must be 'parked' or new.
989*4882a593Smuzhiyun  * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
990*4882a593Smuzhiyun  * @opts: the FQ-modification settings, as defined in the low-level API
991*4882a593Smuzhiyun  *
992*4882a593Smuzhiyun  * The @opts parameter comes from the low-level portal API. Select
993*4882a593Smuzhiyun  * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
994*4882a593Smuzhiyun  * rather than parked. NB, @opts can be NULL.
995*4882a593Smuzhiyun  *
996*4882a593Smuzhiyun  * Note that some fields and options within @opts may be ignored or overwritten
997*4882a593Smuzhiyun  * by the driver;
998*4882a593Smuzhiyun  * 1. the 'count' and 'fqid' fields are always ignored (this operation only
999*4882a593Smuzhiyun  * affects one frame queue: @fq).
1000*4882a593Smuzhiyun  * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
1001*4882a593Smuzhiyun  * 'fqd' structure's 'context_b' field are sometimes overwritten;
1002*4882a593Smuzhiyun  *   - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
1003*4882a593Smuzhiyun  *     initialised to a value used by the driver for demux.
1004*4882a593Smuzhiyun  *   - if context_b is initialised for demux, so is context_a in case stashing
1005*4882a593Smuzhiyun  *     is requested (see item 4).
1006*4882a593Smuzhiyun  * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
1007*4882a593Smuzhiyun  * objects.)
1008*4882a593Smuzhiyun  * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
1009*4882a593Smuzhiyun  * 'dest::channel' field will be overwritten to match the portal used to issue
1010*4882a593Smuzhiyun  * the command. If the WE_DESTWQ write-enable bit had already been set by the
1011*4882a593Smuzhiyun  * caller, the channel workqueue will be left as-is, otherwise the write-enable
1012*4882a593Smuzhiyun  * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
1013*4882a593Smuzhiyun  * isn't set, the destination channel/workqueue fields and the write-enable bit
1014*4882a593Smuzhiyun  * are left as-is.
1015*4882a593Smuzhiyun  * 4. if the driver overwrites context_a/b for demux, then if
1016*4882a593Smuzhiyun  * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
1017*4882a593Smuzhiyun  * context_a.address fields and will leave the stashing fields provided by the
1018*4882a593Smuzhiyun  * user alone, otherwise it will zero out the context_a.stashing fields.
1019*4882a593Smuzhiyun  */
1020*4882a593Smuzhiyun int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun /**
1023*4882a593Smuzhiyun  * qman_schedule_fq - Schedules a FQ
1024*4882a593Smuzhiyun  * @fq: the frame queue object to schedule, must be 'parked'
1025*4882a593Smuzhiyun  *
1026*4882a593Smuzhiyun  * Schedules the frame queue, which must be Parked, which takes it to
1027*4882a593Smuzhiyun  * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
1028*4882a593Smuzhiyun  */
1029*4882a593Smuzhiyun int qman_schedule_fq(struct qman_fq *fq);
1030*4882a593Smuzhiyun 
1031*4882a593Smuzhiyun /**
1032*4882a593Smuzhiyun  * qman_retire_fq - Retires a FQ
1033*4882a593Smuzhiyun  * @fq: the frame queue object to retire
1034*4882a593Smuzhiyun  * @flags: FQ flags (QMAN_FQ_STATE*) if retirement completes immediately
1035*4882a593Smuzhiyun  *
1036*4882a593Smuzhiyun  * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
1037*4882a593Smuzhiyun  * the retirement was started asynchronously, otherwise it returns negative for
1038*4882a593Smuzhiyun  * failure. When this function returns zero, @flags is set to indicate whether
1039*4882a593Smuzhiyun  * the retired FQ is empty and/or whether it has any ORL fragments (to show up
1040*4882a593Smuzhiyun  * as ERNs). Otherwise the corresponding flags will be known when a subsequent
1041*4882a593Smuzhiyun  * FQRN message shows up on the portal's message ring.
1042*4882a593Smuzhiyun  *
1043*4882a593Smuzhiyun  * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
1044*4882a593Smuzhiyun  * Active state), the completion will be via the message ring as a FQRN - but
1045*4882a593Smuzhiyun  * the corresponding callback may occur before this function returns!! Ie. the
1046*4882a593Smuzhiyun  * caller should be prepared to accept the callback as the function is called,
1047*4882a593Smuzhiyun  * not only once it has returned.
1048*4882a593Smuzhiyun  */
1049*4882a593Smuzhiyun int qman_retire_fq(struct qman_fq *fq, u32 *flags);
1050*4882a593Smuzhiyun 
1051*4882a593Smuzhiyun /**
1052*4882a593Smuzhiyun  * qman_oos_fq - Puts a FQ "out of service"
1053*4882a593Smuzhiyun  * @fq: the frame queue object to be put out-of-service, must be 'retired'
1054*4882a593Smuzhiyun  *
1055*4882a593Smuzhiyun  * The frame queue must be retired and empty, and if any order restoration list
1056*4882a593Smuzhiyun  * was released as ERNs at the time of retirement, they must all be consumed.
1057*4882a593Smuzhiyun  */
1058*4882a593Smuzhiyun int qman_oos_fq(struct qman_fq *fq);
1059*4882a593Smuzhiyun 
1060*4882a593Smuzhiyun /*
1061*4882a593Smuzhiyun  * qman_volatile_dequeue - Issue a volatile dequeue command
1062*4882a593Smuzhiyun  * @fq: the frame queue object to dequeue from
1063*4882a593Smuzhiyun  * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
1064*4882a593Smuzhiyun  * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
1065*4882a593Smuzhiyun  *
1066*4882a593Smuzhiyun  * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
1067*4882a593Smuzhiyun  * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
1068*4882a593Smuzhiyun  * the VDQCR is already in use, otherwise returns non-zero for failure. If
1069*4882a593Smuzhiyun  * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
1070*4882a593Smuzhiyun  * the VDQCR command has finished executing (ie. once the callback for the last
1071*4882a593Smuzhiyun  * DQRR entry resulting from the VDQCR command has been called). If not using
1072*4882a593Smuzhiyun  * the FINISH flag, completion can be determined either by detecting the
1073*4882a593Smuzhiyun  * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
1074*4882a593Smuzhiyun  * in the "stat" parameter passed to the FQ's dequeue callback, or by waiting
1075*4882a593Smuzhiyun  * for the QMAN_FQ_STATE_VDQCR bit to disappear.
1076*4882a593Smuzhiyun  */
1077*4882a593Smuzhiyun int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
1078*4882a593Smuzhiyun 
1079*4882a593Smuzhiyun /**
1080*4882a593Smuzhiyun  * qman_enqueue - Enqueue a frame to a frame queue
1081*4882a593Smuzhiyun  * @fq: the frame queue object to enqueue to
1082*4882a593Smuzhiyun  * @fd: a descriptor of the frame to be enqueued
1083*4882a593Smuzhiyun  *
1084*4882a593Smuzhiyun  * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
1085*4882a593Smuzhiyun  * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
1086*4882a593Smuzhiyun  * field is ignored. The return value is non-zero on error, such as ring full.
1087*4882a593Smuzhiyun  */
1088*4882a593Smuzhiyun int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd);
1089*4882a593Smuzhiyun 
1090*4882a593Smuzhiyun /**
1091*4882a593Smuzhiyun  * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
1092*4882a593Smuzhiyun  * @result: is set by the API to the base FQID of the allocated range
1093*4882a593Smuzhiyun  * @count: the number of FQIDs required
1094*4882a593Smuzhiyun  *
1095*4882a593Smuzhiyun  * Returns 0 on success, or a negative error code.
1096*4882a593Smuzhiyun  */
1097*4882a593Smuzhiyun int qman_alloc_fqid_range(u32 *result, u32 count);
1098*4882a593Smuzhiyun #define qman_alloc_fqid(result) qman_alloc_fqid_range(result, 1)
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun /**
1101*4882a593Smuzhiyun  * qman_release_fqid - Release the specified frame queue ID
1102*4882a593Smuzhiyun  * @fqid: the FQID to be released back to the resource pool
1103*4882a593Smuzhiyun  *
1104*4882a593Smuzhiyun  * This function can also be used to seed the allocator with
1105*4882a593Smuzhiyun  * FQID ranges that it can subsequently allocate from.
1106*4882a593Smuzhiyun  * Returns 0 on success, or a negative error code.
1107*4882a593Smuzhiyun  */
1108*4882a593Smuzhiyun int qman_release_fqid(u32 fqid);
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun /**
1111*4882a593Smuzhiyun  * qman_query_fq_np - Queries non-programmable FQD fields
1112*4882a593Smuzhiyun  * @fq: the frame queue object to be queried
1113*4882a593Smuzhiyun  * @np: storage for the queried FQD fields
1114*4882a593Smuzhiyun  */
1115*4882a593Smuzhiyun int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun 	/* Pool-channel management */
1118*4882a593Smuzhiyun /**
1119*4882a593Smuzhiyun  * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
1120*4882a593Smuzhiyun  * @result: is set by the API to the base pool-channel ID of the allocated range
1121*4882a593Smuzhiyun  * @count: the number of pool-channel IDs required
1122*4882a593Smuzhiyun  *
1123*4882a593Smuzhiyun  * Returns 0 on success, or a negative error code.
1124*4882a593Smuzhiyun  */
1125*4882a593Smuzhiyun int qman_alloc_pool_range(u32 *result, u32 count);
1126*4882a593Smuzhiyun #define qman_alloc_pool(result) qman_alloc_pool_range(result, 1)
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun /**
1129*4882a593Smuzhiyun  * qman_release_pool - Release the specified pool-channel ID
1130*4882a593Smuzhiyun  * @id: the pool-chan ID to be released back to the resource pool
1131*4882a593Smuzhiyun  *
1132*4882a593Smuzhiyun  * This function can also be used to seed the allocator with
1133*4882a593Smuzhiyun  * pool-channel ID ranges that it can subsequently allocate from.
1134*4882a593Smuzhiyun  * Returns 0 on success, or a negative error code.
1135*4882a593Smuzhiyun  */
1136*4882a593Smuzhiyun int qman_release_pool(u32 id);
1137*4882a593Smuzhiyun 
1138*4882a593Smuzhiyun 	/* CGR management */
1139*4882a593Smuzhiyun /**
1140*4882a593Smuzhiyun  * qman_create_cgr - Register a congestion group object
1141*4882a593Smuzhiyun  * @cgr: the 'cgr' object, with fields filled in
1142*4882a593Smuzhiyun  * @flags: QMAN_CGR_FLAG_* values
1143*4882a593Smuzhiyun  * @opts: optional state of CGR settings
1144*4882a593Smuzhiyun  *
1145*4882a593Smuzhiyun  * Registers this object to receiving congestion entry/exit callbacks on the
1146*4882a593Smuzhiyun  * portal affine to the cpu portal on which this API is executed. If opts is
1147*4882a593Smuzhiyun  * NULL then only the callback (cgr->cb) function is registered. If @flags
1148*4882a593Smuzhiyun  * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
1149*4882a593Smuzhiyun  * any unspecified parameters) will be used rather than a modify hw hardware
1150*4882a593Smuzhiyun  * (which only modifies the specified parameters).
1151*4882a593Smuzhiyun  */
1152*4882a593Smuzhiyun int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
1153*4882a593Smuzhiyun 		    struct qm_mcc_initcgr *opts);
1154*4882a593Smuzhiyun 
1155*4882a593Smuzhiyun /**
1156*4882a593Smuzhiyun  * qman_delete_cgr - Deregisters a congestion group object
1157*4882a593Smuzhiyun  * @cgr: the 'cgr' object to deregister
1158*4882a593Smuzhiyun  *
1159*4882a593Smuzhiyun  * "Unplugs" this CGR object from the portal affine to the cpu on which this API
1160*4882a593Smuzhiyun  * is executed. This must be excuted on the same affine portal on which it was
1161*4882a593Smuzhiyun  * created.
1162*4882a593Smuzhiyun  */
1163*4882a593Smuzhiyun int qman_delete_cgr(struct qman_cgr *cgr);
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun /**
1166*4882a593Smuzhiyun  * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
1167*4882a593Smuzhiyun  * @cgr: the 'cgr' object to deregister
1168*4882a593Smuzhiyun  *
1169*4882a593Smuzhiyun  * This will select the proper CPU and run there qman_delete_cgr().
1170*4882a593Smuzhiyun  */
1171*4882a593Smuzhiyun void qman_delete_cgr_safe(struct qman_cgr *cgr);
1172*4882a593Smuzhiyun 
1173*4882a593Smuzhiyun /**
1174*4882a593Smuzhiyun  * qman_query_cgr_congested - Queries CGR's congestion status
1175*4882a593Smuzhiyun  * @cgr: the 'cgr' object to query
1176*4882a593Smuzhiyun  * @result: returns 'cgr's congestion status, 1 (true) if congested
1177*4882a593Smuzhiyun  */
1178*4882a593Smuzhiyun int qman_query_cgr_congested(struct qman_cgr *cgr, bool *result);
1179*4882a593Smuzhiyun 
1180*4882a593Smuzhiyun /**
1181*4882a593Smuzhiyun  * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
1182*4882a593Smuzhiyun  * @result: is set by the API to the base CGR ID of the allocated range
1183*4882a593Smuzhiyun  * @count: the number of CGR IDs required
1184*4882a593Smuzhiyun  *
1185*4882a593Smuzhiyun  * Returns 0 on success, or a negative error code.
1186*4882a593Smuzhiyun  */
1187*4882a593Smuzhiyun int qman_alloc_cgrid_range(u32 *result, u32 count);
1188*4882a593Smuzhiyun #define qman_alloc_cgrid(result) qman_alloc_cgrid_range(result, 1)
1189*4882a593Smuzhiyun 
1190*4882a593Smuzhiyun /**
1191*4882a593Smuzhiyun  * qman_release_cgrid - Release the specified CGR ID
1192*4882a593Smuzhiyun  * @id: the CGR ID to be released back to the resource pool
1193*4882a593Smuzhiyun  *
1194*4882a593Smuzhiyun  * This function can also be used to seed the allocator with
1195*4882a593Smuzhiyun  * CGR ID ranges that it can subsequently allocate from.
1196*4882a593Smuzhiyun  * Returns 0 on success, or a negative error code.
1197*4882a593Smuzhiyun  */
1198*4882a593Smuzhiyun int qman_release_cgrid(u32 id);
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun /**
1201*4882a593Smuzhiyun  * qman_is_probed - Check if qman is probed
1202*4882a593Smuzhiyun  *
1203*4882a593Smuzhiyun  * Returns 1 if the qman driver successfully probed, -1 if the qman driver
1204*4882a593Smuzhiyun  * failed to probe or 0 if the qman driver did not probed yet.
1205*4882a593Smuzhiyun  */
1206*4882a593Smuzhiyun int qman_is_probed(void);
1207*4882a593Smuzhiyun 
1208*4882a593Smuzhiyun /**
1209*4882a593Smuzhiyun  * qman_portals_probed - Check if all cpu bound qman portals are probed
1210*4882a593Smuzhiyun  *
1211*4882a593Smuzhiyun  * Returns 1 if all the required cpu bound qman portals successfully probed,
1212*4882a593Smuzhiyun  * -1 if probe errors appeared or 0 if the qman portals did not yet finished
1213*4882a593Smuzhiyun  * probing.
1214*4882a593Smuzhiyun  */
1215*4882a593Smuzhiyun int qman_portals_probed(void);
1216*4882a593Smuzhiyun 
1217*4882a593Smuzhiyun /**
1218*4882a593Smuzhiyun  * qman_dqrr_get_ithresh - Get coalesce interrupt threshold
1219*4882a593Smuzhiyun  * @portal: portal to get the value for
1220*4882a593Smuzhiyun  * @ithresh: threshold pointer
1221*4882a593Smuzhiyun  */
1222*4882a593Smuzhiyun void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh);
1223*4882a593Smuzhiyun 
1224*4882a593Smuzhiyun /**
1225*4882a593Smuzhiyun  * qman_dqrr_set_ithresh - Set coalesce interrupt threshold
1226*4882a593Smuzhiyun  * @portal: portal to set the new value on
1227*4882a593Smuzhiyun  * @ithresh: new threshold value
1228*4882a593Smuzhiyun  *
1229*4882a593Smuzhiyun  * Returns 0 on success, or a negative error code.
1230*4882a593Smuzhiyun  */
1231*4882a593Smuzhiyun int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
1232*4882a593Smuzhiyun 
1233*4882a593Smuzhiyun /**
1234*4882a593Smuzhiyun  * qman_dqrr_get_iperiod - Get coalesce interrupt period
1235*4882a593Smuzhiyun  * @portal: portal to get the value for
1236*4882a593Smuzhiyun  * @iperiod: period pointer
1237*4882a593Smuzhiyun  */
1238*4882a593Smuzhiyun void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod);
1239*4882a593Smuzhiyun 
1240*4882a593Smuzhiyun /**
1241*4882a593Smuzhiyun  * qman_dqrr_set_iperiod - Set coalesce interrupt period
1242*4882a593Smuzhiyun  * @portal: portal to set the new value on
1243*4882a593Smuzhiyun  * @ithresh: new period value
1244*4882a593Smuzhiyun  *
1245*4882a593Smuzhiyun  * Returns 0 on success, or a negative error code.
1246*4882a593Smuzhiyun  */
1247*4882a593Smuzhiyun int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
1248*4882a593Smuzhiyun 
1249*4882a593Smuzhiyun #endif	/* __FSL_QMAN_H */
1250