1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright © 2023 Dmitry Salychev 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. 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 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #ifndef _DPAA2_BUF_H 29 #define _DPAA2_BUF_H 30 31 #include <sys/types.h> 32 #include <sys/param.h> 33 #include <sys/malloc.h> 34 #include <sys/lock.h> 35 #include <sys/mutex.h> 36 #include <sys/systm.h> 37 #include <sys/mbuf.h> 38 39 #include <machine/bus.h> 40 41 #define DPAA2_RX_BUF_SIZE (MJUM9BYTES) 42 43 struct dpaa2_buf { 44 bus_addr_t paddr; 45 caddr_t vaddr; 46 bus_dma_tag_t dmat; 47 bus_dmamap_t dmap; 48 bus_dma_segment_t seg; 49 int nseg; 50 struct mbuf *m; 51 struct dpaa2_buf *sgt; 52 void *opt; 53 }; 54 55 struct dpaa2_bufext_rx { 56 struct mtx dma_mtx; 57 struct dpaa2_channel *ch; 58 }; 59 60 #define DPAA2_BUF_INIT_TAGOPT(__buf, __tag, __opt) do { \ 61 KASSERT((__buf) != NULL, ("%s: buf is NULL", __func__)); \ 62 \ 63 (__buf)->paddr = 0; \ 64 (__buf)->vaddr = NULL; \ 65 (__buf)->dmat = (__tag); \ 66 (__buf)->dmap = NULL; \ 67 (__buf)->seg.ds_addr = 0; \ 68 (__buf)->seg.ds_len = 0; \ 69 (__buf)->nseg = 0; \ 70 (__buf)->m = NULL; \ 71 (__buf)->sgt = NULL; \ 72 (__buf)->opt = (__opt); \ 73 } while(0) 74 #define DPAA2_BUF_INIT(__buf) DPAA2_BUF_INIT_TAGOPT((__buf), NULL, NULL) 75 76 #if defined(INVARIANTS) 77 /* 78 * TXPREP/TXREADY macros allow to verify whether Tx buffer is prepared to be 79 * seeded and/or ready to be used for transmission. 80 * 81 * NOTE: Any modification should be carefully analyzed and justified. 82 */ 83 #define DPAA2_BUF_ASSERT_TXPREP(__buf) do { \ 84 struct dpaa2_buf *__sgt = (__buf)->sgt; \ 85 KASSERT((__sgt) != NULL, ("%s: no S/G table?", __func__)); \ 86 \ 87 KASSERT((__buf)->paddr == 0, ("%s: paddr set?", __func__)); \ 88 KASSERT((__buf)->vaddr == NULL, ("%s: vaddr set?", __func__)); \ 89 KASSERT((__buf)->dmat != NULL, ("%s: no DMA tag?", __func__)); \ 90 KASSERT((__buf)->dmap == NULL, ("%s: DMA map set?", __func__)); \ 91 KASSERT((__buf)->seg.ds_addr == 0, ("%s: already mapped?", __func__)); \ 92 KASSERT((__buf)->seg.ds_len == 0, ("%s: already mapped?", __func__)); \ 93 KASSERT((__buf)->nseg == 0, ("%s: nseg > 0?", __func__)); \ 94 KASSERT((__buf)->m == NULL, ("%s: mbuf set?", __func__)); \ 95 KASSERT((__buf)->opt != NULL, ("%s: no Tx ring?", __func__)); \ 96 \ 97 KASSERT((__sgt)->paddr == 0, ("%s: S/G paddr set?", __func__)); \ 98 KASSERT((__sgt)->vaddr == NULL, ("%s: S/G vaddr set?", __func__)); \ 99 KASSERT((__sgt)->dmat != NULL, ("%s: no S/G DMA tag?", __func__)); \ 100 KASSERT((__sgt)->dmap == NULL, ("%s: S/G DMA map set?", __func__)); \ 101 KASSERT((__sgt)->seg.ds_addr == 0, ("%s: S/G mapped?", __func__)); \ 102 KASSERT((__sgt)->seg.ds_len == 0, ("%s: S/G mapped?", __func__)); \ 103 KASSERT((__sgt)->nseg == 0, ("%s: S/G nseg > 0?", __func__)); \ 104 KASSERT((__sgt)->m == NULL, ("%s: S/G mbuf set?", __func__)); \ 105 KASSERT((__sgt)->opt == (__buf),("%s: buf not linked?", __func__)); \ 106 } while(0) 107 #define DPAA2_BUF_ASSERT_TXREADY(__buf) do { \ 108 struct dpaa2_buf *__sgt = (__buf)->sgt; \ 109 KASSERT((__sgt) != NULL, ("%s: no S/G table?", __func__)); \ 110 \ 111 KASSERT((__buf)->paddr == 0, ("%s: paddr set?", __func__)); \ 112 KASSERT((__buf)->vaddr == NULL, ("%s: vaddr set?", __func__)); \ 113 KASSERT((__buf)->dmat != NULL, ("%s: no DMA tag?", __func__)); \ 114 KASSERT((__buf)->dmap != NULL, ("%s: no DMA map?", __func__)); \ 115 KASSERT((__buf)->seg.ds_addr == 0, ("%s: already mapped?", __func__)); \ 116 KASSERT((__buf)->seg.ds_len == 0, ("%s: already mapped?", __func__)); \ 117 KASSERT((__buf)->nseg == 0, ("%s: nseg > 0?", __func__)); \ 118 KASSERT((__buf)->m == NULL, ("%s: mbuf set?", __func__)); \ 119 KASSERT((__buf)->opt != NULL, ("%s: no Tx ring?", __func__)); \ 120 \ 121 KASSERT((__sgt)->paddr == 0, ("%s: S/G paddr set?", __func__)); \ 122 KASSERT((__sgt)->vaddr != NULL, ("%s: no S/G vaddr?", __func__)); \ 123 KASSERT((__sgt)->dmat != NULL, ("%s: no S/G DMA tag?", __func__)); \ 124 KASSERT((__sgt)->dmap != NULL, ("%s: no S/G DMA map?", __func__)); \ 125 KASSERT((__sgt)->seg.ds_addr == 0, ("%s: S/G mapped?", __func__)); \ 126 KASSERT((__sgt)->seg.ds_len == 0, ("%s: S/G mapped?", __func__)); \ 127 KASSERT((__sgt)->nseg == 0, ("%s: S/G nseg > 0?", __func__)); \ 128 KASSERT((__sgt)->m == NULL, ("%s: S/G mbuf set?", __func__)); \ 129 KASSERT((__sgt)->opt == (__buf),("%s: buf not linked?", __func__)); \ 130 } while(0) 131 #else /* !INVARIANTS */ 132 #define DPAA2_BUF_ASSERT_TXPREP(__buf) do { \ 133 } while(0) 134 #define DPAA2_BUF_ASSERT_TXREADY(__buf) do { \ 135 } while(0) 136 #endif /* INVARIANTS */ 137 138 #if defined(INVARIANTS) 139 /* 140 * RXPREP/RXREADY macros allow to verify whether Rx buffer is prepared to be 141 * seeded and/or ready to be used for reception. 142 * 143 * NOTE: Any modification should be carefully analyzed and justified. 144 */ 145 #define DPAA2_BUF_ASSERT_RXPREP(__buf) do { \ 146 KASSERT((__buf)->paddr == 0, ("%s: paddr set?", __func__)); \ 147 KASSERT((__buf)->vaddr == NULL, ("%s: vaddr set?", __func__)); \ 148 KASSERT((__buf)->dmat != NULL, ("%s: no DMA tag?", __func__)); \ 149 /* KASSERT((__buf)->dmap == NULL, ("%s: DMA map set?", __func__)); */ \ 150 KASSERT((__buf)->seg.ds_addr == 0, ("%s: already mapped?", __func__)); \ 151 KASSERT((__buf)->seg.ds_len == 0, ("%s: already mapped?", __func__)); \ 152 KASSERT((__buf)->nseg == 0, ("%s: nseg > 0?", __func__)); \ 153 KASSERT((__buf)->m == NULL, ("%s: mbuf set?", __func__)); \ 154 KASSERT((__buf)->sgt == NULL, ("%s: S/G table set?", __func__)); \ 155 KASSERT((__buf)->opt != NULL, ("%s: no Rx ext?", __func__)); \ 156 } while(0) 157 #define DPAA2_BUF_ASSERT_RXREADY(__buf) do { \ 158 KASSERT((__buf)->paddr != 0, ("%s: paddr not set?", __func__)); \ 159 KASSERT((__buf)->vaddr != NULL, ("%s: vaddr not set?", __func__)); \ 160 KASSERT((__buf)->dmat != NULL, ("%s: no DMA tag?", __func__)); \ 161 KASSERT((__buf)->dmap != NULL, ("%s: no DMA map?", __func__)); \ 162 KASSERT((__buf)->seg.ds_addr != 0, ("%s: not mapped?", __func__)); \ 163 KASSERT((__buf)->seg.ds_len != 0, ("%s: not mapped?", __func__)); \ 164 KASSERT((__buf)->nseg == 1, ("%s: nseg != 1?", __func__)); \ 165 KASSERT((__buf)->m != NULL, ("%s: no mbuf?", __func__)); \ 166 KASSERT((__buf)->sgt == NULL, ("%s: S/G table set?", __func__)); \ 167 KASSERT((__buf)->opt != NULL, ("%s: no Rx ext?", __func__)); \ 168 } while(0) 169 #else /* !INVARIANTS */ 170 #define DPAA2_BUF_ASSERT_RXPREP(__buf) do { \ 171 } while(0) 172 #define DPAA2_BUF_ASSERT_RXREADY(__buf) do { \ 173 } while(0) 174 #endif /* INVARIANTS */ 175 176 int dpaa2_buf_seed_pool(device_t, device_t, void *, uint32_t, int); 177 int dpaa2_buf_seed_rxb(device_t, struct dpaa2_buf *, int); 178 int dpaa2_buf_seed_txb(device_t, struct dpaa2_buf *); 179 180 #endif /* _DPAA2_BUF_H */ 181