source: rtems-libbsd/linux/drivers/soc/fsl/qbman/qman_test_api.c @ cd089b9

55-freebsd-126-freebsd-12
Last change on this file since cd089b9 was cd089b9, checked in by Sebastian Huber <sebastian.huber@…>, on 05/05/17 at 06:47:39

Linux update to 4.11-rc5

Linux baseline a71c9a1c779f2499fb2afc0553e543f18aff6edf (4.11-rc5).

  • Property mode set to 100644
File size: 6.8 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3#include <rtems/bsd/local/opt_dpaa.h>
4
5/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *     * Redistributions of source code must retain the above copyright
10 *       notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above copyright
12 *       notice, this list of conditions and the following disclaimer in the
13 *       documentation and/or other materials provided with the distribution.
14 *     * Neither the name of Freescale Semiconductor nor the
15 *       names of its contributors may be used to endorse or promote products
16 *       derived from this software without specific prior written permission.
17 *
18 * ALTERNATIVELY, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") as published by the Free Software
20 * Foundation, either version 2 of that License or (at your option) any
21 * later version.
22 *
23 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include "qman_test.h"
36
37#define CGR_ID          27
38#define POOL_ID         2
39#define FQ_FLAGS        QMAN_FQ_FLAG_DYNAMIC_FQID
40#define NUM_ENQUEUES    10
41#define NUM_PARTIAL     4
42#define PORTAL_SDQCR    (QM_SDQCR_SOURCE_CHANNELS | \
43                        QM_SDQCR_TYPE_PRIO_QOS | \
44                        QM_SDQCR_TOKEN_SET(0x98) | \
45                        QM_SDQCR_CHANNELS_DEDICATED | \
46                        QM_SDQCR_CHANNELS_POOL(POOL_ID))
47#define PORTAL_OPAQUE   ((void *)0xf00dbeef)
48#define VDQCR_FLAGS     (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
49
50static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
51                                        struct qman_fq *,
52                                        const struct qm_dqrr_entry *);
53static void cb_ern(struct qman_portal *, struct qman_fq *,
54                   const union qm_mr_entry *);
55static void cb_fqs(struct qman_portal *, struct qman_fq *,
56                   const union qm_mr_entry *);
57
58static struct qm_fd fd, fd_dq;
59static struct qman_fq fq_base = {
60        .cb.dqrr = cb_dqrr,
61        .cb.ern = cb_ern,
62        .cb.fqs = cb_fqs
63};
64static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
65static int retire_complete, sdqcr_complete;
66
67/* Helpers for initialising and "incrementing" a frame descriptor */
68static void fd_init(struct qm_fd *fd)
69{
70        qm_fd_addr_set64(fd, 0xabdeadbeefLLU);
71        qm_fd_set_contig_big(fd, 0x0000ffff);
72        fd->cmd = cpu_to_be32(0xfeedf00d);
73}
74
75static void fd_inc(struct qm_fd *fd)
76{
77        u64 t = qm_fd_addr_get64(fd);
78        int z = t >> 40;
79        unsigned int len, off;
80        enum qm_fd_format fmt;
81
82        t <<= 1;
83        if (z)
84                t |= 1;
85        qm_fd_addr_set64(fd, t);
86
87        fmt = qm_fd_get_format(fd);
88        off = qm_fd_get_offset(fd);
89        len = qm_fd_get_length(fd);
90        len--;
91        qm_fd_set_param(fd, fmt, off, len);
92
93        fd->cmd = cpu_to_be32(be32_to_cpu(fd->cmd) + 1);
94}
95
96/* The only part of the 'fd' we can't memcmp() is the ppid */
97static bool fd_neq(const struct qm_fd *a, const struct qm_fd *b)
98{
99        bool neq = qm_fd_addr_get64(a) != qm_fd_addr_get64(b);
100
101        neq |= qm_fd_get_format(a) != qm_fd_get_format(b);
102        neq |= a->cfg != b->cfg;
103        neq |= a->cmd != b->cmd;
104
105        return neq;
106}
107
108/* test */
109static int do_enqueues(struct qman_fq *fq)
110{
111        unsigned int loop;
112        int err = 0;
113
114        for (loop = 0; loop < NUM_ENQUEUES; loop++) {
115                if (qman_enqueue(fq, &fd)) {
116                        pr_crit("qman_enqueue() failed\n");
117                        err = -EIO;
118                }
119                fd_inc(&fd);
120        }
121
122        return err;
123}
124
125int qman_test_api(void)
126{
127        u32 flags, frmcnt;
128        int err;
129        struct qman_fq *fq = &fq_base;
130
131        pr_info("%s(): Starting\n", __func__);
132        fd_init(&fd);
133        fd_init(&fd_dq);
134
135        /* Initialise (parked) FQ */
136        err = qman_create_fq(0, FQ_FLAGS, fq);
137        if (err) {
138                pr_crit("qman_create_fq() failed\n");
139                goto failed;
140        }
141        err = qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL);
142        if (err) {
143                pr_crit("qman_init_fq() failed\n");
144                goto failed;
145        }
146        /* Do enqueues + VDQCR, twice. (Parked FQ) */
147        err = do_enqueues(fq);
148        if (err)
149                goto failed;
150        pr_info("VDQCR (till-empty);\n");
151        frmcnt = QM_VDQCR_NUMFRAMES_TILLEMPTY;
152        err = qman_volatile_dequeue(fq, VDQCR_FLAGS, frmcnt);
153        if (err) {
154                pr_crit("qman_volatile_dequeue() failed\n");
155                goto failed;
156        }
157        err = do_enqueues(fq);
158        if (err)
159                goto failed;
160        pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
161        frmcnt = QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL);
162        err = qman_volatile_dequeue(fq, VDQCR_FLAGS, frmcnt);
163        if (err) {
164                pr_crit("qman_volatile_dequeue() failed\n");
165                goto failed;
166        }
167        pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
168                NUM_ENQUEUES);
169        frmcnt = QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL);
170        err = qman_volatile_dequeue(fq, VDQCR_FLAGS, frmcnt);
171        if (err) {
172                pr_err("qman_volatile_dequeue() failed\n");
173                goto failed;
174        }
175
176        err = do_enqueues(fq);
177        if (err)
178                goto failed;
179        pr_info("scheduled dequeue (till-empty)\n");
180        err = qman_schedule_fq(fq);
181        if (err) {
182                pr_crit("qman_schedule_fq() failed\n");
183                goto failed;
184        }
185        wait_event(waitqueue, sdqcr_complete);
186
187        /* Retire and OOS the FQ */
188        err = qman_retire_fq(fq, &flags);
189        if (err < 0) {
190                pr_crit("qman_retire_fq() failed\n");
191                goto failed;
192        }
193        wait_event(waitqueue, retire_complete);
194        if (flags & QMAN_FQ_STATE_BLOCKOOS) {
195                err = -EIO;
196                pr_crit("leaking frames\n");
197                goto failed;
198        }
199        err = qman_oos_fq(fq);
200        if (err) {
201                pr_crit("qman_oos_fq() failed\n");
202                goto failed;
203        }
204        qman_destroy_fq(fq);
205        pr_info("%s(): Finished\n", __func__);
206        return 0;
207
208failed:
209        WARN_ON(1);
210        return err;
211}
212
213static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
214                                        struct qman_fq *fq,
215                                        const struct qm_dqrr_entry *dq)
216{
217        if (WARN_ON(fd_neq(&fd_dq, &dq->fd))) {
218                pr_err("BADNESS: dequeued frame doesn't match;\n");
219                return qman_cb_dqrr_consume;
220        }
221        fd_inc(&fd_dq);
222        if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_neq(&fd_dq, &fd)) {
223                sdqcr_complete = 1;
224                wake_up(&waitqueue);
225        }
226        return qman_cb_dqrr_consume;
227}
228
229static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
230                   const union qm_mr_entry *msg)
231{
232        pr_crit("cb_ern() unimplemented");
233        WARN_ON(1);
234}
235
236static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
237                   const union qm_mr_entry *msg)
238{
239        u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
240
241        if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI)) {
242                pr_crit("unexpected FQS message");
243                WARN_ON(1);
244                return;
245        }
246#ifndef __rtems__
247        pr_info("Retirement message received\n");
248#endif /* __rtems__ */
249        retire_complete = 1;
250        wake_up(&waitqueue);
251}
Note: See TracBrowser for help on using the repository browser.