1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
|
/*-
* Copyright (c) 2011-2012 Semihalf.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _QMAN_H
#define _QMAN_H
#include <sys/vmem.h>
#include <machine/vmparam.h>
struct qman_fq;
struct qman_fq;
struct dpaa_fd;
struct qman_portal;
/**
* @group QMan private defines/declarations
* @{
*/
/**
* Maximum number of frame queues in all QMans.
*/
#define QMAN_MAX_FQIDS 16
/**
* Pool channel common to all software portals.
* @note Value of 0 reflects the e_QM_FQ_CHANNEL_POOL1 from e_QmFQChannel
* type used in qman_fq_create().
*/
#define QMAN_COMMON_POOL_CHANNEL 0
#define QMAN_FQID_BASE 1
/* Counters */
#define QMAN_COUNTER_FRAME 0
#define QMAN_COUNTER_BYTES 1
/*
* Portal defines
*/
#define QMAN_CE_PA(base) (base)
#define QMAN_CI_PA(base) ((base) + 0x100000)
#define QMAN_PORTAL_CE_PA(base, n) \
(QMAN_CE_PA(base) + ((n) * QMAN_PORTAL_CE_SIZE))
#define QMAN_PORTAL_CI_PA(base, n) \
(QMAN_CI_PA(base) + ((n) * QMAN_PORTAL_CI_SIZE))
struct qman_softc {
device_t sc_dev; /* device handle */
int sc_rrid; /* register rid */
struct resource *sc_rres; /* register resource */
int sc_irid; /* interrupt rid */
struct resource *sc_ires; /* interrupt resource */
vmem_t *sc_fqalloc;
vmem_t *sc_qpalloc;
vmem_t *sc_cgalloc;
void *sc_intr_cookie;
int sc_qman_base_channel;
int sc_qman_major;
vm_paddr_t sc_qp_pa; /* QMAN portal PA */
int sc_fq_cpu[QMAN_MAX_FQIDS];
};
struct qman_fd {
uint64_t dd:2;
uint64_t liodn_off:6;
uint64_t bpid:8;
uint64_t eliodn_off:4;
uint64_t _rsvd0:4;
uint64_t addr:40;
union {
struct {
uint32_t format:3;
uint32_t offset:9;
uint32_t length:20;
};
struct {
uint32_t format2:3;
uint32_t wlength:29;
};
};
uint32_t cmd_stat;
};
_Static_assert(sizeof(struct qman_fd) == 16, "qman_fd size mismatch");
struct qman_dqrr_entry {
uint8_t verb;
uint8_t stat;
uint16_t seqnum;
uint8_t tok;
uint8_t _rsvd0[3];
uint32_t fqid;
uint32_t ctxb;
struct qman_fd fd;
uint8_t _rsvd1[32];
};
/* Bits for qman_dqrr_entry fields */
#define QMAN_DQRR_STAT_FQ_EMPTY 0x80
#define QMAN_DQRR_STAT_FQ_HELD_ACTIVE 0x40
#define QMAN_DQRR_STAT_FQ_FORCED 0x20
#define QMAN_DQRR_STAT_HAS_FRAME 0x10
#define QMAN_DQRR_STAT_VDQCR 0x02
#define QMAN_DQRR_STAT_EXPIRED 0x01
struct qman_mr_entry {
union {
struct {
uint8_t verb;
uint8_t data[63];
};
struct {
uint8_t verb;
uint8_t dca;
uint16_t seqnum;
uint32_t rc:8;
uint32_t orp:24;
uint32_t fqid;
uint32_t tag;
struct qman_fd fd;
uint8_t _rsvd[32];
} ern;
struct {
uint8_t verb;
uint8_t fqs;
uint8_t _rsvd0[6];
uint32_t fqid;
uint32_t ctxb;
uint8_t _rsvd1[48];
} fqscn;
};
};
_Static_assert(sizeof(struct qman_mr_entry) == 64, "bad sizeof qman_mr");
/** @> */
typedef int (*qman_cb_dqrr)(device_t, struct qman_fq *,
struct qman_fd *, void *);
typedef void (*qman_cb_mr)(device_t, struct qman_fq *,
struct qman_mr_entry *);
typedef void (*qman_cb_flush)(struct qman_fq *, void *);
struct qman_cb {
qman_cb_dqrr dqrr;
qman_cb_mr ern;
qman_cb_mr fqscn;
/*
* Optional post-poll hook. If set, qman_portal_loop_dqrr()
* calls it once per poll cycle on every FQ that had a frame
* dispatched, after all DQRR entries have been drained.
* Consumers use this for aggregation flushes (e.g., LRO
* flush, batched if_input) that must happen outside the
* per-frame dispatch path.
*/
qman_cb_flush flush;
void *ctx;
};
/**
* @group QMan bus interface
* @{
*/
int qman_attach(device_t dev);
int qman_detach(device_t dev);
int qman_suspend(device_t dev);
int qman_resume(device_t dev);
int qman_shutdown(device_t dev);
/** @> */
int qman_create_affine_portal(device_t, vm_offset_t, vm_offset_t, int);
void qman_set_sdest(uint16_t, int);
/**
* @group QMan API
* @{
*/
/**
* Create Frame Queue Range.
*
* @param fqids_num Number of frame queues in the range.
*
* @param channel Dedicated channel serviced by this
* Frame Queue Range.
*
* @param wq Work Queue Number within the channel.
*
* @param force_fqid If TRUE, fore allocation of specific
* FQID. Notice that there can not be two
* frame queues with the same ID in the
* system.
*
* @param fqid_or_align FQID if @force_fqid == TRUE, alignment
* of FQIDs entries otherwise.
*
* @param init_parked If TRUE, FQ state is initialized to
* "parked" state on creation. Otherwise,
* to "scheduled" state.
*
* @param hold_active If TRUE, the FQ may be held in the
* portal in "held active" state in
* anticipation of more frames being
* dequeued from it after the head frame
* is removed from the FQ and the dequeue
* response is returned. If FALSE the
* "held_active" state of the FQ is not
* allowed. This affects only on queues
* destined to software portals. Refer to
* the 6.3.4.6 of DPAA Reference Manual.
*
* @param prefer_in_cache If TRUE, prefer this FQR to be in QMan
* internal cache memory for all states.
*
* @param congst_avoid_ena If TRUE, enable congestion avoidance
* mechanism.
*
* @param congst_group A handle to the congestion group. Only
* relevant when @congst_avoid_ena == TRUE.
*
* @param overhead_accounting_len For each frame add this number for CG
* calculation (may be negative), if 0 -
* disable feature.
*
* @param tail_drop_threshold If not 0 - enable tail drop on this
* FQR.
*
* @return A handle to newly created FQR object.
*/
struct qman_fq *qman_fq_create(uint32_t fqids_num, int channel,
uint8_t wq, bool force_fqid, uint32_t fqid_or_align, bool init_parked,
bool hold_active, bool prefer_in_cache, bool congst_avoid_ena,
void *congst_group, int8_t overhead_accounting_len,
uint32_t tail_drop_threshold,
uint8_t annotation_cl, uint8_t data_cl);
/**
* Free Frame Queue Range.
*
* @param fq A handle to FQR to be freed.
* @return E_OK on success; error code otherwise.
*/
int qman_fq_free(struct qman_fq *fq);
/**
* Register the callback function.
* The callback function will be called when a frame comes from this FQR.
*
* @param fq A handle to FQR.
* @param callback A pointer to the callback function.
* @param app A pointer to the user's data.
* @return E_OK on success; error code otherwise.
*/
/*
* Register a post-poll flush callback on @fq. Called once per poll
* cycle on any FQ that had at least one dispatched frame during
* that cycle, after all DQRR entries were drained. Reuses the
* per-FQ ctx registered via qman_fq_register_cb(). May be called
* before or after qman_fq_register_cb() but only makes sense if the
* DQRR callback is also set.
*/
int qman_fq_register_flush_cb(struct qman_fq *fq, qman_cb_flush flush);
int qman_fq_register_cb(struct qman_fq *fq, qman_cb_dqrr callback,
void *ctx);
/**
* Enqueue a frame on a given FQ.
*
* @param fq A handle to FQ.
* @param frame A frame to be enqueued to the transmission.
* @return E_OK on success; error code otherwise.
*/
int qman_fq_enqueue(struct qman_fq *fq, struct dpaa_fd *frame);
/**
* Get one of the FQ counter's value.
*
* @param fq A handle to FQ.
* @param counter The requested counter.
* @return Counter's current value.
*/
uint32_t qman_fq_get_counter(struct qman_fq *fq, int counter);
/**
* Pull frame from FQ.
*
* @param fq A handle to FQ.
* @param frame The received frame.
* @return E_OK on success; error code otherwise.
*/
int qman_fq_pull_frame(struct qman_fq *fq, struct dpaa_fd *frame);
/**
* Get FQID of the FQ.
* @param fq A handle to FQ.
* @return FQID of the FQ.
*/
uint32_t qman_fq_get_fqid(struct qman_fq *fq);
/*
* Allocate a QMan channel to be used with an FQ.
* @return Channel ID
*/
int qman_alloc_channel(void);
/*
* Free a channel
* @param chan Channel ID returned from qman_alloc_channel().
*/
void qman_free_channel(int);
/*
* Look up the pool channel for @cpu. Each portal has a dedicated channel, and
* there is one portal per CPU.
*/
int qman_percpu_channel(int cpu);
/*
* Reserve a contiguous range of @count FQIDs (needed by callers that
* program a KeyGen-style base+mask distribution and then create the
* individual FQs one-by-one with force_fqid=true). @align is the
* required base alignment in FQIDs (0 for no requirement, or the
* range size for the power-of-two-aligned base FMan KeyGen wants).
* Returns 0 on success and writes the base FQID to *basep.
*/
int qman_alloc_fqid_range(uint32_t count, uint32_t align, uint32_t *basep);
void qman_free_fqid_range(uint32_t base, uint32_t count);
/**
* Poll frames from QMan.
* This polls frames from the current software portal.
*
* @param source Type of frames to be polled.
* @return E_OK on success; error otherwise.
*/
int qman_poll(int source);
/**
* General received frame callback.
* This is called, when user did not register his own callback for a given
* frame queue range (fq).
*/
int qman_received_frame_callback(void *ctx, struct qman_fq *fq,
void *qm_portal, uint32_t fqid_offset, struct dpaa_fd *frame);
/**
* General rejected frame callback.
* This is called, when user did not register his own callback for a given
* frame queue range (fq).
*/
int qman_rejected_frame_callback(void *ctx, struct qman_fq *fq,
void *qm_portal, uint32_t fqid_offset, struct dpaa_fd *frame,
void *qm_rejected_frame_info);
/** @} */
#endif /* QMAN_H */
|