1 /*        $NetBSD: ldcvar.h,v 1.2 2025/02/05 20:46:26 palle Exp $     */
2 /*        $OpenBSD: ldcvar.h,v 1.6 2014/09/29 17:43:29 kettenis Exp $ */
3 /*
4  * Copyright (c) 2009 Mark Kettenis
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * LDC queues.
21  */
22 
23 #include <sys/mutex.h>
24 
25 struct ldc_queue {
26           kmutex_t  lq_mtx;
27 #if OPENBSD_BUSDMA
28           bus_dmamap_t        lq_map;
29           bus_dma_segment_t lq_seg;
30 #endif
31           vaddr_t             lq_va;
32           int                 lq_nentries;
33 };
34 
35 #if OPENBSD_BUSDMA
36 struct ldc_queue *ldc_queue_alloc(bus_dma_tag_t, int);
37 void      ldc_queue_free(bus_dma_tag_t, struct ldc_queue *);
38 #else
39 struct ldc_queue *ldc_queue_alloc(int);
40 void      ldc_queue_free(struct ldc_queue *);
41 #endif
42 
43 /*
44  * LDC virtual link layer protocol.
45  */
46 
47 #define LDC_VERSION_MAJOR     1
48 #define LDC_VERSION_MINOR     0
49 
50 #define LDC_PKT_PAYLOAD                 56
51 
52 struct ldc_pkt {
53           uint8_t             type;
54           uint8_t             stype;
55           uint8_t             ctrl;
56           uint8_t             env;
57           uint32_t  seqid;
58 
59           uint16_t  major;
60           uint16_t  minor;
61           uint32_t  _reserved[13];
62 };
63 
64 /* Packet types. */
65 #define LDC_CTRL    0x01
66 #define LDC_DATA    0x02
67 #define LDC_ERR               0x10
68 
69 /* Packet subtypes. */
70 #define LDC_INFO    0x01
71 #define LDC_ACK               0x02
72 #define LDC_NACK    0x04
73 
74 /* Control info values. */
75 #define LDC_VERS    0x01
76 #define LDC_RTS               0x02
77 #define LDC_RTR               0x03
78 #define LDC_RDX               0x04
79 
80 /* Packet envelope. */
81 #define LDC_MODE_RAW                    0x00
82 #define LDC_MODE_UNRELIABLE   0x01
83 #define LDC_MODE_RELIABLE     0x03
84 
85 #define LDC_LEN_MASK          0x3f
86 #define LDC_FRAG_MASK         0xc0
87 #define LDC_FRAG_START        0x40
88 #define LDC_FRAG_STOP         0x80
89 
90 /*
91  * XXX Get rid of the +8 once we no longer need to store the header of
92  * the first packet.
93  */
94 #define LDC_MSG_MAX (128 + 8)
95 
96 struct ldc_conn {
97           uint64_t  lc_id;
98 
99           struct ldc_queue *lc_txq;
100           struct ldc_queue *lc_rxq;
101           uint64_t  lc_tx_state;
102           uint64_t  lc_rx_state;
103 
104           uint32_t  lc_tx_seqid;
105           uint8_t             lc_state;
106 #define LDC_SND_VERS          1
107 #define LDC_RCV_VERS          2
108 #define LDC_SND_RTS 3
109 #define LDC_SND_RTR 4
110 #define LDC_SND_RDX 5
111 
112           uint64_t  lc_msg[LDC_MSG_MAX / 8];
113           size_t              lc_len;
114 
115           void                *lc_sc;
116           void                (*lc_reset)(struct ldc_conn *);
117           void                (*lc_start)(struct ldc_conn *);
118           void                (*lc_rx_data)(struct ldc_conn *, struct ldc_pkt *);
119 };
120 
121 void      ldc_rx_ctrl(struct ldc_conn *, struct ldc_pkt *);
122 void      ldc_rx_data(struct ldc_conn *, struct ldc_pkt *);
123 
124 int       ldc_send_vers(struct ldc_conn *);
125 int       ldc_send_unreliable(struct ldc_conn *, void *, size_t);
126 
127 void      ldc_reset(struct ldc_conn *);
128 
129 /*
130  * LDC map tables.
131  */
132 
133 struct ldc_map_slot {
134           uint64_t  entry;
135           uint64_t  cookie;
136 };
137 
138 #define LDC_MTE_R   0x0000000000000010ULL
139 #define LDC_MTE_W   0x0000000000000020ULL
140 #define LDC_MTE_X   0x0000000000000040ULL
141 #define LDC_MTE_IOR 0x0000000000000080ULL
142 #define LDC_MTE_IOW 0x0000000000000100ULL
143 #define LDC_MTE_CPR 0x0000000000000200ULL
144 #define LDC_MTE_CPW 0x0000000000000400ULL
145 #define LDC_MTE_RA_MASK       0x007fffffffffe000ULL
146 
147 struct ldc_map {
148 #if OPENBSD_BUSDMA
149           bus_dmamap_t                  lm_map;
150           bus_dma_segment_t   lm_seg;
151 #endif
152           struct ldc_map_slot *lm_slot;
153           int                           lm_nentries;
154           int                           lm_next;
155           int                           lm_count;
156 };
157 
158 #if OPENBSD_BUSDMA
159 struct ldc_map *ldc_map_alloc(bus_dma_tag_t, int);
160 void      ldc_map_free(bus_dma_tag_t, struct ldc_map *);
161 #else
162 struct ldc_map *ldc_map_alloc(int);
163 void      ldc_map_free(struct ldc_map *);
164 #endif
165 
166 struct ldc_cookie {
167           uint64_t  addr;
168           uint64_t  size;
169 };
170