a03f3e23a660f9d91f7e41f0e06bd37f910a1169
[openwrt/staging/ynezz.git] /
1 From c91f8c8c94c5e8a25d0d46d6cb26c0c48ba04f8f Mon Sep 17 00:00:00 2001
2 From: Roy Pledge <roy.pledge@nxp.com>
3 Date: Wed, 4 Oct 2017 15:36:06 -0400
4 Subject: [PATCH] soc: fsl: dpio: Add Support for Order Restoration
5
6 Add DPIO support for HW assisted order restoration
7
8 Signed-off-by: Roy Pledge <roy.pledge@nxp.com>
9 ---
10 drivers/soc/fsl/dpio/dpio-service.c | 105 ++++++++++++++++++++++++++++++++++++
11 drivers/soc/fsl/dpio/qbman-portal.c | 37 +++++++++++++
12 drivers/soc/fsl/dpio/qbman-portal.h | 3 ++
13 include/soc/fsl/dpaa2-io.h | 14 ++++-
14 4 files changed, 158 insertions(+), 1 deletion(-)
15
16 --- a/drivers/soc/fsl/dpio/dpio-service.c
17 +++ b/drivers/soc/fsl/dpio/dpio-service.c
18 @@ -707,3 +707,108 @@ int dpaa2_io_query_bp_count(struct dpaa2
19 return 0;
20 }
21 EXPORT_SYMBOL_GPL(dpaa2_io_query_bp_count);
22 +
23 +/**
24 + * dpaa2_io_service_enqueue_orp_fq() - Enqueue a frame to a frame queue with
25 + * order restoration
26 + * @d: the given DPIO service.
27 + * @fqid: the given frame queue id.
28 + * @fd: the frame descriptor which is enqueued.
29 + * @orpid: the order restoration point ID
30 + * @seqnum: the order sequence number
31 + * @last: must be set for the final frame if seqnum is shared (spilt frame)
32 + *
33 + * Performs an enqueue to a frame queue using the specified order restoration
34 + * point. The QMan device will ensure the order of frames placed on the
35 + * queue will be ordered as per the sequence number.
36 + *
37 + * In the case a frame is split it is possible to enqueue using the same
38 + * sequence number more than once. The final frame in a shared sequence number
39 + * most be indicated by setting last = 1. For non shared sequence numbers
40 + * last = 1 must always be set.
41 + *
42 + * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready,
43 + * or -ENODEV if there is no dpio service.
44 + */
45 +int dpaa2_io_service_enqueue_orp_fq(struct dpaa2_io *d, u32 fqid,
46 + const struct dpaa2_fd *fd, u16 orpid,
47 + u16 seqnum, int last)
48 +{
49 + struct qbman_eq_desc ed;
50 +
51 + d = service_select(d);
52 + if (!d)
53 + return -ENODEV;
54 + qbman_eq_desc_clear(&ed);
55 + qbman_eq_desc_set_orp(&ed, 0, orpid, seqnum, !last);
56 + qbman_eq_desc_set_fq(&ed, fqid);
57 + return qbman_swp_enqueue(d->swp, &ed, fd);
58 +}
59 +EXPORT_SYMBOL(dpaa2_io_service_enqueue_orp_fq);
60 +
61 +/**
62 + * dpaa2_io_service_enqueue_orp_qd() - Enqueue a frame to a queueing destination
63 + * with order restoration
64 + * @d: the given DPIO service.
65 + * @qdid: the given queuing destination id.
66 + * @fd: the frame descriptor which is enqueued.
67 + * @orpid: the order restoration point ID
68 + * @seqnum: the order sequence number
69 + * @last: must be set for the final frame if seqnum is shared (spilt frame)
70 + *
71 + * Performs an enqueue to a frame queue using the specified order restoration
72 + * point. The QMan device will ensure the order of frames placed on the
73 + * queue will be ordered as per the sequence number.
74 + *
75 + * In the case a frame is split it is possible to enqueue using the same
76 + * sequence number more than once. The final frame in a shared sequence number
77 + * most be indicated by setting last = 1. For non shared sequence numbers
78 + * last = 1 must always be set.
79 + *
80 + * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready,
81 + * or -ENODEV if there is no dpio service.
82 + */
83 +int dpaa2_io_service_enqueue_orp_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
84 + u16 qdbin, const struct dpaa2_fd *fd,
85 + u16 orpid, u16 seqnum, int last)
86 +{
87 + struct qbman_eq_desc ed;
88 +
89 + d = service_select(d);
90 + if (!d)
91 + return -ENODEV;
92 + qbman_eq_desc_clear(&ed);
93 + qbman_eq_desc_set_orp(&ed, 0, orpid, seqnum, !last);
94 + qbman_eq_desc_set_qd(&ed, qdid, qdbin, prio);
95 + return qbman_swp_enqueue(d->swp, &ed, fd);
96 +}
97 +EXPORT_SYMBOL_GPL(dpaa2_io_service_enqueue_orp_qd);
98 +
99 +/**
100 + * dpaa2_io_service_orp_seqnum_drop() - Remove a sequence number from
101 + * an order restoration list
102 + * @d: the given DPIO service.
103 + * @orpid: Order restoration point to remove a sequence number from
104 + * @seqnum: Sequence number to remove
105 + *
106 + * Removes a frames sequence number from an order restoration point without
107 + * enqueing the frame. Used to indicate that the order restoration hardware
108 + * should not expect to see this sequence number. Typically used to indicate
109 + * a frame was terminated or dropped from a flow.
110 + *
111 + * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready,
112 + * or -ENODEV if there is no dpio service.
113 + */
114 +int dpaa2_io_service_orp_seqnum_drop(struct dpaa2_io *d, u16 orpid, u16 seqnum)
115 +{
116 + struct qbman_eq_desc ed;
117 + struct dpaa2_fd fd;
118 +
119 + d = service_select(d);
120 + if (!d)
121 + return -ENODEV;
122 + qbman_eq_desc_clear(&ed);
123 + qbman_eq_desc_set_orp_hole(&ed, orpid, seqnum);
124 + return qbman_swp_enqueue(d->swp, &ed, &fd);
125 +}
126 +EXPORT_SYMBOL_GPL(dpaa2_io_service_orp_seqnum_drop);
127 --- a/drivers/soc/fsl/dpio/qbman-portal.c
128 +++ b/drivers/soc/fsl/dpio/qbman-portal.c
129 @@ -413,6 +413,43 @@ void qbman_eq_desc_set_no_orp(struct qbm
130 d->verb |= enqueue_rejects_to_fq;
131 }
132
133 +/**
134 + * qbman_eq_desc_set_orp() - Set order-restoration in the enqueue descriptor
135 + * @d: the enqueue descriptor.
136 + * @response_success: 1 = enqueue with response always; 0 = enqueue with
137 + * rejections returned on a FQ.
138 + * @oprid: the order point record id.
139 + * @seqnum: the order restoration sequence number.
140 + * @incomplete: indicates whether this is the last fragments using the same
141 + * sequence number.
142 + */
143 +void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
144 + u16 oprid, u16 seqnum, int incomplete)
145 +{
146 + d->verb |= (1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT);
147 + if (respond_success)
148 + d->verb |= enqueue_response_always;
149 + else
150 + d->verb |= enqueue_rejects_to_fq;
151 + d->orpid = cpu_to_le16(oprid);
152 + d->seqnum = cpu_to_le16((!!incomplete << 14) | seqnum);
153 +}
154 +
155 +/**
156 + * qbman_eq_desc_set_orp_hole() - fill a hole in the order-restoration sequence
157 + * without any enqueue
158 + * @d: the enqueue descriptor.
159 + * @oprid: the order point record id.
160 + * @seqnum: the order restoration sequence number.
161 + */
162 +void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, u16 oprid,
163 + u16 seqnum)
164 +{
165 + d->verb |= (1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT) | enqueue_empty;
166 + d->orpid = cpu_to_le16(oprid);
167 + d->seqnum = cpu_to_le16(seqnum);
168 +}
169 +
170 /*
171 * Exactly one of the following descriptor "targets" should be set. (Calling any
172 * one of these will replace the effect of any prior call to one of these.)
173 --- a/drivers/soc/fsl/dpio/qbman-portal.h
174 +++ b/drivers/soc/fsl/dpio/qbman-portal.h
175 @@ -167,6 +167,9 @@ int qbman_result_has_new_result(struct q
176
177 void qbman_eq_desc_clear(struct qbman_eq_desc *d);
178 void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success);
179 +void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success,
180 + u16 oprid, u16 seqnum, int incomplete);
181 +void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, u16 oprid, u16 seqnum);
182 void qbman_eq_desc_set_token(struct qbman_eq_desc *d, u8 token);
183 void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid);
184 void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid,
185 --- a/include/soc/fsl/dpaa2-io.h
186 +++ b/include/soc/fsl/dpaa2-io.h
187 @@ -1,7 +1,7 @@
188 /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
189 /*
190 * Copyright 2014-2016 Freescale Semiconductor Inc.
191 - * Copyright NXP
192 + * Copyright 2017 NXP
193 *
194 */
195 #ifndef __FSL_DPAA2_IO_H
196 @@ -121,6 +121,18 @@ struct dpaa2_io_store *dpaa2_io_store_cr
197 void dpaa2_io_store_destroy(struct dpaa2_io_store *s);
198 struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last);
199
200 +/* Order Restoration Support */
201 +int dpaa2_io_service_enqueue_orp_fq(struct dpaa2_io *d, u32 fqid,
202 + const struct dpaa2_fd *fd, u16 orpid,
203 + u16 seqnum, int last);
204 +
205 +int dpaa2_io_service_enqueue_orp_qd(struct dpaa2_io *d, u32 qdid, u8 prio,
206 + u16 qdbin, const struct dpaa2_fd *fd,
207 + u16 orpid, u16 seqnum, int last);
208 +
209 +int dpaa2_io_service_orp_seqnum_drop(struct dpaa2_io *d, u16 orpid,
210 + u16 seqnum);
211 +
212 int dpaa2_io_query_fq_count(struct dpaa2_io *d, u32 fqid,
213 u32 *fcnt, u32 *bcnt);
214 int dpaa2_io_query_bp_count(struct dpaa2_io *d, u16 bpid,