Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #ifndef __ROC_MBOX_PRIV_H__
6 : : #define __ROC_MBOX_PRIV_H__
7 : :
8 : : #include <errno.h>
9 : : #include <stdbool.h>
10 : : #include <stdint.h>
11 : :
12 : : #define SZ_64K (64ULL * 1024ULL)
13 : : #define SZ_1K (1ULL * 1024ULL)
14 : : #define MBOX_SIZE SZ_64K
15 : :
16 : : /* AF/PF: PF initiated, PF/VF VF initiated */
17 : : #define MBOX_DOWN_RX_START 0
18 : : #define MBOX_DOWN_RX_SIZE (46 * SZ_1K)
19 : : #define MBOX_DOWN_TX_START (MBOX_DOWN_RX_START + MBOX_DOWN_RX_SIZE)
20 : : #define MBOX_DOWN_TX_SIZE (16 * SZ_1K)
21 : : /* AF/PF: AF initiated, PF/VF PF initiated */
22 : : #define MBOX_UP_RX_START (MBOX_DOWN_TX_START + MBOX_DOWN_TX_SIZE)
23 : : #define MBOX_UP_RX_SIZE SZ_1K
24 : : #define MBOX_UP_TX_START (MBOX_UP_RX_START + MBOX_UP_RX_SIZE)
25 : : #define MBOX_UP_TX_SIZE SZ_1K
26 : :
27 : : #if MBOX_UP_TX_SIZE + MBOX_UP_TX_START != MBOX_SIZE
28 : : #error "Incorrect mailbox area sizes"
29 : : #endif
30 : :
31 : : #define INTR_MASK(pfvfs) ((pfvfs < 64) ? (BIT_ULL(pfvfs) - 1) : (~0ull))
32 : :
33 : : #define MBOX_RSP_TIMEOUT 3000 /* Time to wait for mbox response in ms */
34 : :
35 : : #define MBOX_MSG_ALIGN 16 /* Align mbox msg start to 16bytes */
36 : :
37 : : /* Mailbox directions */
38 : : #define MBOX_DIR_AFPF 0 /* AF replies to PF */
39 : : #define MBOX_DIR_PFAF 1 /* PF sends messages to AF */
40 : : #define MBOX_DIR_PFVF 2 /* PF replies to VF */
41 : : #define MBOX_DIR_VFPF 3 /* VF sends messages to PF */
42 : : #define MBOX_DIR_AFPF_UP 4 /* AF sends messages to PF */
43 : : #define MBOX_DIR_PFAF_UP 5 /* PF replies to AF */
44 : : #define MBOX_DIR_PFVF_UP 6 /* PF sends messages to VF */
45 : : #define MBOX_DIR_VFPF_UP 7 /* VF replies to PF */
46 : :
47 : : struct mbox_dev {
48 : : void *mbase; /* This dev's mbox region */
49 : : plt_spinlock_t mbox_lock;
50 : : uint16_t msg_size; /* Total msg size to be sent */
51 : : uint16_t rsp_size; /* Total rsp size to be sure the reply is ok */
52 : : uint16_t num_msgs; /* No of msgs sent or waiting for response */
53 : : uint16_t msgs_acked; /* No of msgs for which response is received */
54 : : };
55 : :
56 : : struct mbox {
57 : : uintptr_t hwbase; /* Mbox region advertised by HW */
58 : : uintptr_t reg_base; /* CSR base for this dev */
59 : : uint64_t trigger; /* Trigger mbox notification */
60 : : uint16_t tr_shift; /* Mbox trigger shift */
61 : : uint64_t rx_start; /* Offset of Rx region in mbox memory */
62 : : uint64_t tx_start; /* Offset of Tx region in mbox memory */
63 : : uint16_t rx_size; /* Size of Rx region */
64 : : uint16_t tx_size; /* Size of Tx region */
65 : : uint16_t ndevs; /* The number of peers */
66 : : struct mbox_dev *dev;
67 : : uint64_t intr_offset; /* Offset to interrupt register */
68 : : uint32_t rsp_tmo;
69 : : };
70 : :
71 : : const char *mbox_id2name(uint16_t id);
72 : : int mbox_id2size(uint16_t id);
73 : : void mbox_reset(struct mbox *mbox, int devid);
74 : : int mbox_init(struct mbox *mbox, uintptr_t hwbase, uintptr_t reg_base, int direction, int ndevsi,
75 : : uint64_t intr_offset);
76 : : void mbox_fini(struct mbox *mbox);
77 : : void mbox_msg_send(struct mbox *mbox, int devid);
78 : : void mbox_msg_send_up(struct mbox *mbox, int devid);
79 : : bool mbox_wait_for_zero(struct mbox *mbox, int devid);
80 : : int mbox_wait_for_rsp(struct mbox *mbox, int devid);
81 : : int mbox_wait_for_rsp_tmo(struct mbox *mbox, int devid, uint32_t tmo);
82 : : int mbox_get_rsp(struct mbox *mbox, int devid, void **msg);
83 : : int mbox_get_rsp_tmo(struct mbox *mbox, int devid, void **msg, uint32_t tmo);
84 : : int mbox_get_availmem(struct mbox *mbox, int devid);
85 : : struct mbox_msghdr *mbox_alloc_msg_rsp(struct mbox *mbox, int devid, int size,
86 : : int size_rsp);
87 : :
88 : : static inline struct mbox_msghdr *
89 : : mbox_alloc_msg(struct mbox *mbox, int devid, int size)
90 : : {
91 : 0 : return mbox_alloc_msg_rsp(mbox, devid, size, 0);
92 : : }
93 : :
94 : : static inline void
95 : : mbox_req_init(uint16_t mbox_id, void *msghdr)
96 : : {
97 : : struct mbox_msghdr *hdr = msghdr;
98 : :
99 : 0 : hdr->sig = MBOX_REQ_SIG;
100 : 0 : hdr->ver = MBOX_VERSION;
101 : 0 : hdr->id = mbox_id;
102 : 0 : hdr->pcifunc = 0;
103 : : }
104 : :
105 : : static inline void
106 : : mbox_rsp_init(uint16_t mbox_id, void *msghdr)
107 : : {
108 : : struct mbox_msghdr *hdr = msghdr;
109 : :
110 : 0 : hdr->sig = MBOX_RSP_SIG;
111 : 0 : hdr->rc = -ETIMEDOUT;
112 [ # # # # ]: 0 : hdr->id = mbox_id;
113 : : }
114 : :
115 : : static inline bool
116 : : mbox_nonempty(struct mbox *mbox, int devid)
117 : : {
118 : : struct mbox_dev *mdev = &mbox->dev[devid];
119 : : bool ret;
120 : :
121 : : plt_spinlock_lock(&mdev->mbox_lock);
122 : : ret = mdev->num_msgs != 0;
123 : : plt_spinlock_unlock(&mdev->mbox_lock);
124 : :
125 : : return ret;
126 : : }
127 : :
128 : : static inline int
129 : 0 : mbox_process(struct mbox *mbox)
130 : : {
131 : 0 : mbox_msg_send(mbox, 0);
132 : 0 : return mbox_get_rsp(mbox, 0, NULL);
133 : : }
134 : :
135 : : static inline int
136 : : mbox_process_msg(struct mbox *mbox, void **msg)
137 : : {
138 : 0 : mbox_msg_send(mbox, 0);
139 : 0 : return mbox_get_rsp(mbox, 0, msg);
140 : : }
141 : :
142 : : static inline int
143 : : mbox_process_tmo(struct mbox *mbox, uint32_t tmo)
144 : : {
145 : : mbox_msg_send(mbox, 0);
146 : : return mbox_get_rsp_tmo(mbox, 0, NULL, tmo);
147 : : }
148 : :
149 : : static inline int
150 : : mbox_process_msg_tmo(struct mbox *mbox, void **msg, uint32_t tmo)
151 : : {
152 : : mbox_msg_send(mbox, 0);
153 : : return mbox_get_rsp_tmo(mbox, 0, msg, tmo);
154 : : }
155 : :
156 : : static inline struct mbox *
157 : : mbox_get(struct mbox *mbox)
158 : : {
159 : 0 : struct mbox_dev *mdev = &mbox->dev[0];
160 : 0 : plt_spinlock_lock(&mdev->mbox_lock);
161 : : return mbox;
162 : : }
163 : :
164 : : static inline void
165 : : mbox_put(struct mbox *mbox)
166 : : {
167 : 0 : struct mbox_dev *mdev = &mbox->dev[0];
168 : 0 : plt_spinlock_unlock(&mdev->mbox_lock);
169 : 0 : }
170 : :
171 : : int send_ready_msg(struct mbox *mbox, uint16_t *pf_func /* out */);
172 : : int reply_invalid_msg(struct mbox *mbox, int devid, uint16_t pf_func,
173 : : uint16_t id);
174 : :
175 : : #define M(_name, _id, _fn_name, _req_type, _rsp_type) \
176 : : static inline struct _req_type *mbox_alloc_msg_##_fn_name( \
177 : : struct mbox *mbox) \
178 : : { \
179 : : struct _req_type *req; \
180 : : req = (struct _req_type *)mbox_alloc_msg_rsp( \
181 : : mbox, 0, sizeof(struct _req_type), \
182 : : sizeof(struct _rsp_type)); \
183 : : if (!req) \
184 : : return NULL; \
185 : : req->hdr.sig = MBOX_REQ_SIG; \
186 : : req->hdr.id = _id; \
187 : : plt_mbox_dbg("id=0x%x (%s)", req->hdr.id, \
188 : : mbox_id2name(req->hdr.id)); \
189 : : return req; \
190 : : }
191 : :
192 [ # # ]: 0 : MBOX_MESSAGES
193 : : #undef M
194 : :
195 : : /* This is required for copy operations from device memory which do not work on
196 : : * addresses which are unaligned to 16B. This is because of specific
197 : : * optimizations to libc memcpy.
198 : : */
199 : : static inline volatile void *
200 : : mbox_memcpy(volatile void *d, const volatile void *s, size_t l)
201 : : {
202 : : const volatile uint8_t *sb;
203 : : volatile uint8_t *db;
204 : : size_t i;
205 : :
206 [ # # # # : 0 : if (!d || !s)
# # # # ]
207 : : return NULL;
208 : : db = (volatile uint8_t *)d;
209 : : sb = (const volatile uint8_t *)s;
210 [ # # # # : 0 : for (i = 0; i < l; i++)
# # # # #
# # # # #
# # ]
211 : 0 : db[i] = sb[i];
212 : : return d;
213 : : }
214 : :
215 : : /* This is required for memory operations from device memory which do not
216 : : * work on addresses which are unaligned to 16B. This is because of specific
217 : : * optimizations to libc memset.
218 : : */
219 : : static inline void
220 : : mbox_memset(volatile void *d, uint8_t val, size_t l)
221 : : {
222 : : volatile uint8_t *db;
223 : : size_t i = 0;
224 : :
225 [ # # ]: 0 : if (!d || !l)
226 : : return;
227 : : db = (volatile uint8_t *)d;
228 [ # # ]: 0 : for (i = 0; i < l; i++)
229 : 0 : db[i] = val;
230 : : }
231 : :
232 : : #endif /* __ROC_MBOX_PRIV_H__ */
|