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