Tom Rini | 10e4779 | 2018-05-06 17:58:06 -0400 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
Prabhakar Kushwaha | cfd9fbf | 2015-03-19 09:20:45 -0700 | [diff] [blame] | 2 | /* |
| 3 | * Copyright (C) 2014 Freescale Semiconductor |
Prabhakar Kushwaha | cfd9fbf | 2015-03-19 09:20:45 -0700 | [diff] [blame] | 4 | */ |
| 5 | #ifndef __FSL_DPAA_FD_H |
| 6 | #define __FSL_DPAA_FD_H |
| 7 | |
| 8 | /* Place-holder for FDs, we represent it via the simplest form that we need for |
| 9 | * now. Different overlays may be needed to support different options, etc. (It |
| 10 | * is impractical to define One True Struct, because the resulting encoding |
| 11 | * routines (lots of read-modify-writes) would be worst-case performance whether |
| 12 | * or not circumstances required them.) */ |
| 13 | struct dpaa_fd { |
| 14 | union { |
| 15 | u32 words[8]; |
| 16 | struct dpaa_fd_simple { |
| 17 | u32 addr_lo; |
| 18 | u32 addr_hi; |
| 19 | u32 len; |
| 20 | /* offset in the MS 16 bits, BPID in the LS 16 bits */ |
| 21 | u32 bpid_offset; |
| 22 | u32 frc; /* frame context */ |
| 23 | /* "err", "va", "cbmt", "asal", [...] */ |
| 24 | u32 ctrl; |
| 25 | /* flow context */ |
| 26 | u32 flc_lo; |
| 27 | u32 flc_hi; |
| 28 | } simple; |
| 29 | }; |
| 30 | }; |
| 31 | |
| 32 | enum dpaa_fd_format { |
| 33 | dpaa_fd_single = 0, |
| 34 | dpaa_fd_list, |
| 35 | dpaa_fd_sg |
| 36 | }; |
| 37 | |
| 38 | static inline u64 ldpaa_fd_get_addr(const struct dpaa_fd *fd) |
| 39 | { |
| 40 | return (u64)((((uint64_t)fd->simple.addr_hi) << 32) |
| 41 | + fd->simple.addr_lo); |
| 42 | } |
| 43 | |
| 44 | static inline void ldpaa_fd_set_addr(struct dpaa_fd *fd, u64 addr) |
| 45 | { |
| 46 | fd->simple.addr_hi = upper_32_bits(addr); |
| 47 | fd->simple.addr_lo = lower_32_bits(addr); |
| 48 | } |
| 49 | |
| 50 | static inline u32 ldpaa_fd_get_len(const struct dpaa_fd *fd) |
| 51 | { |
| 52 | return fd->simple.len; |
| 53 | } |
| 54 | |
| 55 | static inline void ldpaa_fd_set_len(struct dpaa_fd *fd, u32 len) |
| 56 | { |
| 57 | fd->simple.len = len; |
| 58 | } |
| 59 | |
| 60 | static inline uint16_t ldpaa_fd_get_offset(const struct dpaa_fd *fd) |
| 61 | { |
| 62 | return (uint16_t)(fd->simple.bpid_offset >> 16) & 0x0FFF; |
| 63 | } |
| 64 | |
| 65 | static inline void ldpaa_fd_set_offset(struct dpaa_fd *fd, uint16_t offset) |
| 66 | { |
| 67 | fd->simple.bpid_offset &= 0xF000FFFF; |
| 68 | fd->simple.bpid_offset |= (u32)offset << 16; |
| 69 | } |
| 70 | |
| 71 | static inline uint16_t ldpaa_fd_get_bpid(const struct dpaa_fd *fd) |
| 72 | { |
| 73 | return (uint16_t)(fd->simple.bpid_offset & 0xFFFF); |
| 74 | } |
| 75 | |
| 76 | static inline void ldpaa_fd_set_bpid(struct dpaa_fd *fd, uint16_t bpid) |
| 77 | { |
| 78 | fd->simple.bpid_offset &= 0xFFFF0000; |
| 79 | fd->simple.bpid_offset |= (u32)bpid; |
| 80 | } |
| 81 | |
| 82 | /* When frames are dequeued, the FDs show up inside "dequeue" result structures |
| 83 | * (if at all, not all dequeue results contain valid FDs). This structure type |
| 84 | * is intentionally defined without internal detail, and the only reason it |
| 85 | * isn't declared opaquely (without size) is to allow the user to provide |
| 86 | * suitably-sized (and aligned) memory for these entries. */ |
| 87 | struct ldpaa_dq { |
| 88 | uint32_t dont_manipulate_directly[16]; |
| 89 | }; |
| 90 | |
| 91 | /* Parsing frame dequeue results */ |
| 92 | #define LDPAA_DQ_STAT_FQEMPTY 0x80 |
| 93 | #define LDPAA_DQ_STAT_HELDACTIVE 0x40 |
| 94 | #define LDPAA_DQ_STAT_FORCEELIGIBLE 0x20 |
| 95 | #define LDPAA_DQ_STAT_VALIDFRAME 0x10 |
| 96 | #define LDPAA_DQ_STAT_ODPVALID 0x04 |
| 97 | #define LDPAA_DQ_STAT_VOLATILE 0x02 |
| 98 | #define LDPAA_DQ_STAT_EXPIRED 0x01 |
| 99 | uint32_t ldpaa_dq_flags(const struct ldpaa_dq *); |
| 100 | static inline int ldpaa_dq_is_pull(const struct ldpaa_dq *dq) |
| 101 | { |
| 102 | return (int)(ldpaa_dq_flags(dq) & LDPAA_DQ_STAT_VOLATILE); |
| 103 | } |
| 104 | static inline int ldpaa_dq_is_pull_complete( |
| 105 | const struct ldpaa_dq *dq) |
| 106 | { |
| 107 | return (int)(ldpaa_dq_flags(dq) & LDPAA_DQ_STAT_EXPIRED); |
| 108 | } |
| 109 | /* seqnum/odpid are valid only if VALIDFRAME and ODPVALID flags are TRUE */ |
| 110 | uint16_t ldpaa_dq_seqnum(const struct ldpaa_dq *); |
| 111 | uint16_t ldpaa_dq_odpid(const struct ldpaa_dq *); |
| 112 | uint32_t ldpaa_dq_fqid(const struct ldpaa_dq *); |
| 113 | uint32_t ldpaa_dq_byte_count(const struct ldpaa_dq *); |
| 114 | uint32_t ldpaa_dq_frame_count(const struct ldpaa_dq *); |
| 115 | uint32_t ldpaa_dq_fqd_ctx_hi(const struct ldpaa_dq *); |
| 116 | uint32_t ldpaa_dq_fqd_ctx_lo(const struct ldpaa_dq *); |
| 117 | /* get the Frame Descriptor */ |
| 118 | const struct dpaa_fd *ldpaa_dq_fd(const struct ldpaa_dq *); |
| 119 | |
| 120 | #endif /* __FSL_DPAA_FD_H */ |