xref: /dpdk/drivers/common/cnxk/roc_mbox_priv.h (revision fa4ee2d4318810b4b116fbe4869d78850ceaf9a2)
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 *
mbox_alloc_msg(struct mbox * mbox,int devid,int size)89 mbox_alloc_msg(struct mbox *mbox, int devid, int size)
90 {
91 	return mbox_alloc_msg_rsp(mbox, devid, size, 0);
92 }
93 
94 static inline void
mbox_req_init(uint16_t mbox_id,void * msghdr)95 mbox_req_init(uint16_t mbox_id, void *msghdr)
96 {
97 	struct mbox_msghdr *hdr = msghdr;
98 
99 	hdr->sig = MBOX_REQ_SIG;
100 	hdr->ver = MBOX_VERSION;
101 	hdr->id = mbox_id;
102 	hdr->pcifunc = 0;
103 }
104 
105 static inline void
mbox_rsp_init(uint16_t mbox_id,void * msghdr)106 mbox_rsp_init(uint16_t mbox_id, void *msghdr)
107 {
108 	struct mbox_msghdr *hdr = msghdr;
109 
110 	hdr->sig = MBOX_RSP_SIG;
111 	hdr->rc = -ETIMEDOUT;
112 	hdr->id = mbox_id;
113 }
114 
115 static inline bool
mbox_nonempty(struct mbox * mbox,int devid)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
mbox_process(struct mbox * mbox)129 mbox_process(struct mbox *mbox)
130 {
131 	mbox_msg_send(mbox, 0);
132 	return mbox_get_rsp(mbox, 0, NULL);
133 }
134 
135 static inline int
mbox_process_msg(struct mbox * mbox,void ** msg)136 mbox_process_msg(struct mbox *mbox, void **msg)
137 {
138 	mbox_msg_send(mbox, 0);
139 	return mbox_get_rsp(mbox, 0, msg);
140 }
141 
142 static inline int
mbox_process_tmo(struct mbox * mbox,uint32_t tmo)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
mbox_process_msg_tmo(struct mbox * mbox,void ** msg,uint32_t tmo)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 *
mbox_get(struct mbox * mbox)157 mbox_get(struct mbox *mbox)
158 {
159 	struct mbox_dev *mdev = &mbox->dev[0];
160 	plt_spinlock_lock(&mdev->mbox_lock);
161 	return mbox;
162 }
163 
164 static inline void
mbox_put(struct mbox * mbox)165 mbox_put(struct mbox *mbox)
166 {
167 	struct mbox_dev *mdev = &mbox->dev[0];
168 	plt_spinlock_unlock(&mdev->mbox_lock);
169 }
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 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 *
mbox_memcpy(volatile void * d,const volatile void * s,size_t l)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 	if (!d || !s)
207 		return NULL;
208 	db = (volatile uint8_t *)d;
209 	sb = (const volatile uint8_t *)s;
210 	for (i = 0; i < l; i++)
211 		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
mbox_memset(volatile void * d,uint8_t val,size_t l)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 	if (!d || !l)
226 		return;
227 	db = (volatile uint8_t *)d;
228 	for (i = 0; i < l; i++)
229 		db[i] = val;
230 }
231 
232 #endif /* __ROC_MBOX_PRIV_H__ */
233