103cc9bd9SJerin Jacob /* SPDX-License-Identifier: BSD-3-Clause
203cc9bd9SJerin Jacob * Copyright(C) 2021 Marvell.
303cc9bd9SJerin Jacob */
403cc9bd9SJerin Jacob
503cc9bd9SJerin Jacob #ifndef __ROC_MBOX_PRIV_H__
603cc9bd9SJerin Jacob #define __ROC_MBOX_PRIV_H__
703cc9bd9SJerin Jacob
803cc9bd9SJerin Jacob #include <errno.h>
903cc9bd9SJerin Jacob #include <stdbool.h>
1003cc9bd9SJerin Jacob #include <stdint.h>
1103cc9bd9SJerin Jacob
1203cc9bd9SJerin Jacob #define SZ_64K (64ULL * 1024ULL)
1303cc9bd9SJerin Jacob #define SZ_1K (1ULL * 1024ULL)
1403cc9bd9SJerin Jacob #define MBOX_SIZE SZ_64K
1503cc9bd9SJerin Jacob
1603cc9bd9SJerin Jacob /* AF/PF: PF initiated, PF/VF VF initiated */
1703cc9bd9SJerin Jacob #define MBOX_DOWN_RX_START 0
1803cc9bd9SJerin Jacob #define MBOX_DOWN_RX_SIZE (46 * SZ_1K)
1903cc9bd9SJerin Jacob #define MBOX_DOWN_TX_START (MBOX_DOWN_RX_START + MBOX_DOWN_RX_SIZE)
2003cc9bd9SJerin Jacob #define MBOX_DOWN_TX_SIZE (16 * SZ_1K)
2103cc9bd9SJerin Jacob /* AF/PF: AF initiated, PF/VF PF initiated */
2203cc9bd9SJerin Jacob #define MBOX_UP_RX_START (MBOX_DOWN_TX_START + MBOX_DOWN_TX_SIZE)
2303cc9bd9SJerin Jacob #define MBOX_UP_RX_SIZE SZ_1K
2403cc9bd9SJerin Jacob #define MBOX_UP_TX_START (MBOX_UP_RX_START + MBOX_UP_RX_SIZE)
2503cc9bd9SJerin Jacob #define MBOX_UP_TX_SIZE SZ_1K
2603cc9bd9SJerin Jacob
2703cc9bd9SJerin Jacob #if MBOX_UP_TX_SIZE + MBOX_UP_TX_START != MBOX_SIZE
2803cc9bd9SJerin Jacob #error "Incorrect mailbox area sizes"
2903cc9bd9SJerin Jacob #endif
3003cc9bd9SJerin Jacob
3103cc9bd9SJerin Jacob #define INTR_MASK(pfvfs) ((pfvfs < 64) ? (BIT_ULL(pfvfs) - 1) : (~0ull))
3203cc9bd9SJerin Jacob
3303cc9bd9SJerin Jacob #define MBOX_RSP_TIMEOUT 3000 /* Time to wait for mbox response in ms */
3403cc9bd9SJerin Jacob
3503cc9bd9SJerin Jacob #define MBOX_MSG_ALIGN 16 /* Align mbox msg start to 16bytes */
3603cc9bd9SJerin Jacob
3703cc9bd9SJerin Jacob /* Mailbox directions */
3803cc9bd9SJerin Jacob #define MBOX_DIR_AFPF 0 /* AF replies to PF */
3903cc9bd9SJerin Jacob #define MBOX_DIR_PFAF 1 /* PF sends messages to AF */
4003cc9bd9SJerin Jacob #define MBOX_DIR_PFVF 2 /* PF replies to VF */
4103cc9bd9SJerin Jacob #define MBOX_DIR_VFPF 3 /* VF sends messages to PF */
4203cc9bd9SJerin Jacob #define MBOX_DIR_AFPF_UP 4 /* AF sends messages to PF */
4303cc9bd9SJerin Jacob #define MBOX_DIR_PFAF_UP 5 /* PF replies to AF */
4403cc9bd9SJerin Jacob #define MBOX_DIR_PFVF_UP 6 /* PF sends messages to VF */
4503cc9bd9SJerin Jacob #define MBOX_DIR_VFPF_UP 7 /* VF replies to PF */
4603cc9bd9SJerin Jacob
4703cc9bd9SJerin Jacob struct mbox_dev {
4803cc9bd9SJerin Jacob void *mbase; /* This dev's mbox region */
4903cc9bd9SJerin Jacob plt_spinlock_t mbox_lock;
5003cc9bd9SJerin Jacob uint16_t msg_size; /* Total msg size to be sent */
5103cc9bd9SJerin Jacob uint16_t rsp_size; /* Total rsp size to be sure the reply is ok */
5203cc9bd9SJerin Jacob uint16_t num_msgs; /* No of msgs sent or waiting for response */
5303cc9bd9SJerin Jacob uint16_t msgs_acked; /* No of msgs for which response is received */
5403cc9bd9SJerin Jacob };
5503cc9bd9SJerin Jacob
5603cc9bd9SJerin Jacob struct mbox {
5703cc9bd9SJerin Jacob uintptr_t hwbase; /* Mbox region advertised by HW */
5803cc9bd9SJerin Jacob uintptr_t reg_base; /* CSR base for this dev */
5903cc9bd9SJerin Jacob uint64_t trigger; /* Trigger mbox notification */
6003cc9bd9SJerin Jacob uint16_t tr_shift; /* Mbox trigger shift */
6103cc9bd9SJerin Jacob uint64_t rx_start; /* Offset of Rx region in mbox memory */
6203cc9bd9SJerin Jacob uint64_t tx_start; /* Offset of Tx region in mbox memory */
6303cc9bd9SJerin Jacob uint16_t rx_size; /* Size of Rx region */
6403cc9bd9SJerin Jacob uint16_t tx_size; /* Size of Tx region */
6503cc9bd9SJerin Jacob uint16_t ndevs; /* The number of peers */
6603cc9bd9SJerin Jacob struct mbox_dev *dev;
6703cc9bd9SJerin Jacob uint64_t intr_offset; /* Offset to interrupt register */
6803cc9bd9SJerin Jacob uint32_t rsp_tmo;
6903cc9bd9SJerin Jacob };
7003cc9bd9SJerin Jacob
7103cc9bd9SJerin Jacob const char *mbox_id2name(uint16_t id);
7203cc9bd9SJerin Jacob int mbox_id2size(uint16_t id);
7303cc9bd9SJerin Jacob void mbox_reset(struct mbox *mbox, int devid);
74*fa4ee2d4SHarman Kalra int mbox_init(struct mbox *mbox, uintptr_t hwbase, uintptr_t reg_base, int direction, int ndevsi,
75*fa4ee2d4SHarman Kalra uint64_t intr_offset);
7603cc9bd9SJerin Jacob void mbox_fini(struct mbox *mbox);
7703cc9bd9SJerin Jacob void mbox_msg_send(struct mbox *mbox, int devid);
78*fa4ee2d4SHarman Kalra void mbox_msg_send_up(struct mbox *mbox, int devid);
79*fa4ee2d4SHarman Kalra bool mbox_wait_for_zero(struct mbox *mbox, int devid);
8003cc9bd9SJerin Jacob int mbox_wait_for_rsp(struct mbox *mbox, int devid);
8103cc9bd9SJerin Jacob int mbox_wait_for_rsp_tmo(struct mbox *mbox, int devid, uint32_t tmo);
8203cc9bd9SJerin Jacob int mbox_get_rsp(struct mbox *mbox, int devid, void **msg);
8303cc9bd9SJerin Jacob int mbox_get_rsp_tmo(struct mbox *mbox, int devid, void **msg, uint32_t tmo);
8403cc9bd9SJerin Jacob int mbox_get_availmem(struct mbox *mbox, int devid);
8503cc9bd9SJerin Jacob struct mbox_msghdr *mbox_alloc_msg_rsp(struct mbox *mbox, int devid, int size,
8603cc9bd9SJerin Jacob int size_rsp);
8703cc9bd9SJerin Jacob
8803cc9bd9SJerin Jacob static inline struct mbox_msghdr *
mbox_alloc_msg(struct mbox * mbox,int devid,int size)8903cc9bd9SJerin Jacob mbox_alloc_msg(struct mbox *mbox, int devid, int size)
9003cc9bd9SJerin Jacob {
9103cc9bd9SJerin Jacob return mbox_alloc_msg_rsp(mbox, devid, size, 0);
9203cc9bd9SJerin Jacob }
9303cc9bd9SJerin Jacob
9403cc9bd9SJerin Jacob static inline void
mbox_req_init(uint16_t mbox_id,void * msghdr)9503cc9bd9SJerin Jacob mbox_req_init(uint16_t mbox_id, void *msghdr)
9603cc9bd9SJerin Jacob {
9703cc9bd9SJerin Jacob struct mbox_msghdr *hdr = msghdr;
9803cc9bd9SJerin Jacob
9903cc9bd9SJerin Jacob hdr->sig = MBOX_REQ_SIG;
10003cc9bd9SJerin Jacob hdr->ver = MBOX_VERSION;
10103cc9bd9SJerin Jacob hdr->id = mbox_id;
10203cc9bd9SJerin Jacob hdr->pcifunc = 0;
10303cc9bd9SJerin Jacob }
10403cc9bd9SJerin Jacob
10503cc9bd9SJerin Jacob static inline void
mbox_rsp_init(uint16_t mbox_id,void * msghdr)10603cc9bd9SJerin Jacob mbox_rsp_init(uint16_t mbox_id, void *msghdr)
10703cc9bd9SJerin Jacob {
10803cc9bd9SJerin Jacob struct mbox_msghdr *hdr = msghdr;
10903cc9bd9SJerin Jacob
11003cc9bd9SJerin Jacob hdr->sig = MBOX_RSP_SIG;
11103cc9bd9SJerin Jacob hdr->rc = -ETIMEDOUT;
11203cc9bd9SJerin Jacob hdr->id = mbox_id;
11303cc9bd9SJerin Jacob }
11403cc9bd9SJerin Jacob
11503cc9bd9SJerin Jacob static inline bool
mbox_nonempty(struct mbox * mbox,int devid)11603cc9bd9SJerin Jacob mbox_nonempty(struct mbox *mbox, int devid)
11703cc9bd9SJerin Jacob {
11803cc9bd9SJerin Jacob struct mbox_dev *mdev = &mbox->dev[devid];
11903cc9bd9SJerin Jacob bool ret;
12003cc9bd9SJerin Jacob
12103cc9bd9SJerin Jacob plt_spinlock_lock(&mdev->mbox_lock);
12203cc9bd9SJerin Jacob ret = mdev->num_msgs != 0;
12303cc9bd9SJerin Jacob plt_spinlock_unlock(&mdev->mbox_lock);
12403cc9bd9SJerin Jacob
12503cc9bd9SJerin Jacob return ret;
12603cc9bd9SJerin Jacob }
12703cc9bd9SJerin Jacob
12803cc9bd9SJerin Jacob static inline int
mbox_process(struct mbox * mbox)12903cc9bd9SJerin Jacob mbox_process(struct mbox *mbox)
13003cc9bd9SJerin Jacob {
13103cc9bd9SJerin Jacob mbox_msg_send(mbox, 0);
13203cc9bd9SJerin Jacob return mbox_get_rsp(mbox, 0, NULL);
13303cc9bd9SJerin Jacob }
13403cc9bd9SJerin Jacob
13503cc9bd9SJerin Jacob static inline int
mbox_process_msg(struct mbox * mbox,void ** msg)13603cc9bd9SJerin Jacob mbox_process_msg(struct mbox *mbox, void **msg)
13703cc9bd9SJerin Jacob {
13803cc9bd9SJerin Jacob mbox_msg_send(mbox, 0);
13903cc9bd9SJerin Jacob return mbox_get_rsp(mbox, 0, msg);
14003cc9bd9SJerin Jacob }
14103cc9bd9SJerin Jacob
14203cc9bd9SJerin Jacob static inline int
mbox_process_tmo(struct mbox * mbox,uint32_t tmo)14303cc9bd9SJerin Jacob mbox_process_tmo(struct mbox *mbox, uint32_t tmo)
14403cc9bd9SJerin Jacob {
14503cc9bd9SJerin Jacob mbox_msg_send(mbox, 0);
14603cc9bd9SJerin Jacob return mbox_get_rsp_tmo(mbox, 0, NULL, tmo);
14703cc9bd9SJerin Jacob }
14803cc9bd9SJerin Jacob
14903cc9bd9SJerin Jacob static inline int
mbox_process_msg_tmo(struct mbox * mbox,void ** msg,uint32_t tmo)15003cc9bd9SJerin Jacob mbox_process_msg_tmo(struct mbox *mbox, void **msg, uint32_t tmo)
15103cc9bd9SJerin Jacob {
15203cc9bd9SJerin Jacob mbox_msg_send(mbox, 0);
15303cc9bd9SJerin Jacob return mbox_get_rsp_tmo(mbox, 0, msg, tmo);
15403cc9bd9SJerin Jacob }
15503cc9bd9SJerin Jacob
15644a9307cSRakesh Kudurumalla static inline struct mbox *
mbox_get(struct mbox * mbox)15744a9307cSRakesh Kudurumalla mbox_get(struct mbox *mbox)
15844a9307cSRakesh Kudurumalla {
15944a9307cSRakesh Kudurumalla struct mbox_dev *mdev = &mbox->dev[0];
16044a9307cSRakesh Kudurumalla plt_spinlock_lock(&mdev->mbox_lock);
16144a9307cSRakesh Kudurumalla return mbox;
16244a9307cSRakesh Kudurumalla }
16344a9307cSRakesh Kudurumalla
16444a9307cSRakesh Kudurumalla static inline void
mbox_put(struct mbox * mbox)16544a9307cSRakesh Kudurumalla mbox_put(struct mbox *mbox)
16644a9307cSRakesh Kudurumalla {
16744a9307cSRakesh Kudurumalla struct mbox_dev *mdev = &mbox->dev[0];
16844a9307cSRakesh Kudurumalla plt_spinlock_unlock(&mdev->mbox_lock);
16944a9307cSRakesh Kudurumalla }
17044a9307cSRakesh Kudurumalla
17103cc9bd9SJerin Jacob int send_ready_msg(struct mbox *mbox, uint16_t *pf_func /* out */);
17203cc9bd9SJerin Jacob int reply_invalid_msg(struct mbox *mbox, int devid, uint16_t pf_func,
17303cc9bd9SJerin Jacob uint16_t id);
17403cc9bd9SJerin Jacob
17503cc9bd9SJerin Jacob #define M(_name, _id, _fn_name, _req_type, _rsp_type) \
17603cc9bd9SJerin Jacob static inline struct _req_type *mbox_alloc_msg_##_fn_name( \
17703cc9bd9SJerin Jacob struct mbox *mbox) \
17803cc9bd9SJerin Jacob { \
17903cc9bd9SJerin Jacob struct _req_type *req; \
18003cc9bd9SJerin Jacob req = (struct _req_type *)mbox_alloc_msg_rsp( \
18103cc9bd9SJerin Jacob mbox, 0, sizeof(struct _req_type), \
18203cc9bd9SJerin Jacob sizeof(struct _rsp_type)); \
18303cc9bd9SJerin Jacob if (!req) \
18403cc9bd9SJerin Jacob return NULL; \
18503cc9bd9SJerin Jacob req->hdr.sig = MBOX_REQ_SIG; \
18603cc9bd9SJerin Jacob req->hdr.id = _id; \
18703cc9bd9SJerin Jacob plt_mbox_dbg("id=0x%x (%s)", req->hdr.id, \
18803cc9bd9SJerin Jacob mbox_id2name(req->hdr.id)); \
18903cc9bd9SJerin Jacob return req; \
19003cc9bd9SJerin Jacob }
19103cc9bd9SJerin Jacob
19203cc9bd9SJerin Jacob MBOX_MESSAGES
19303cc9bd9SJerin Jacob #undef M
19403cc9bd9SJerin Jacob
19503cc9bd9SJerin Jacob /* This is required for copy operations from device memory which do not work on
19603cc9bd9SJerin Jacob * addresses which are unaligned to 16B. This is because of specific
19703cc9bd9SJerin Jacob * optimizations to libc memcpy.
19803cc9bd9SJerin Jacob */
19903cc9bd9SJerin Jacob static inline volatile void *
mbox_memcpy(volatile void * d,const volatile void * s,size_t l)20003cc9bd9SJerin Jacob mbox_memcpy(volatile void *d, const volatile void *s, size_t l)
20103cc9bd9SJerin Jacob {
20203cc9bd9SJerin Jacob const volatile uint8_t *sb;
20303cc9bd9SJerin Jacob volatile uint8_t *db;
20403cc9bd9SJerin Jacob size_t i;
20503cc9bd9SJerin Jacob
20603cc9bd9SJerin Jacob if (!d || !s)
20703cc9bd9SJerin Jacob return NULL;
20803cc9bd9SJerin Jacob db = (volatile uint8_t *)d;
20903cc9bd9SJerin Jacob sb = (const volatile uint8_t *)s;
21003cc9bd9SJerin Jacob for (i = 0; i < l; i++)
21103cc9bd9SJerin Jacob db[i] = sb[i];
21203cc9bd9SJerin Jacob return d;
21303cc9bd9SJerin Jacob }
21403cc9bd9SJerin Jacob
21503cc9bd9SJerin Jacob /* This is required for memory operations from device memory which do not
21603cc9bd9SJerin Jacob * work on addresses which are unaligned to 16B. This is because of specific
21703cc9bd9SJerin Jacob * optimizations to libc memset.
21803cc9bd9SJerin Jacob */
21903cc9bd9SJerin Jacob static inline void
mbox_memset(volatile void * d,uint8_t val,size_t l)22003cc9bd9SJerin Jacob mbox_memset(volatile void *d, uint8_t val, size_t l)
22103cc9bd9SJerin Jacob {
22203cc9bd9SJerin Jacob volatile uint8_t *db;
22303cc9bd9SJerin Jacob size_t i = 0;
22403cc9bd9SJerin Jacob
22503cc9bd9SJerin Jacob if (!d || !l)
22603cc9bd9SJerin Jacob return;
22703cc9bd9SJerin Jacob db = (volatile uint8_t *)d;
22803cc9bd9SJerin Jacob for (i = 0; i < l; i++)
22903cc9bd9SJerin Jacob db[i] = val;
23003cc9bd9SJerin Jacob }
23103cc9bd9SJerin Jacob
23203cc9bd9SJerin Jacob #endif /* __ROC_MBOX_PRIV_H__ */
233