1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Marvell Octeon EP (EndPoint) Ethernet Driver
3  *
4  * Copyright (C) 2020 Marvell.
5  *
6  */
7  #ifndef __OCTEP_CTRL_MBOX_H__
8 #define __OCTEP_CTRL_MBOX_H__
9 
10 /*              barmem structure
11  * |===========================================|
12  * |Info (16 + 120 + 120 = 256 bytes)          |
13  * |-------------------------------------------|
14  * |magic number (8 bytes)                     |
15  * |bar memory size (4 bytes)                  |
16  * |reserved (4 bytes)                         |
17  * |-------------------------------------------|
18  * |host version (8 bytes)                     |
19  * |host status (8 bytes)                      |
20  * |host reserved (104 bytes)                  |
21  * |-------------------------------------------|
22  * |fw version (8 bytes)                       |
23  * |fw status (8 bytes)                        |
24  * |fw reserved (104 bytes)                    |
25  * |===========================================|
26  * |Host to Fw Queue info (16 bytes)           |
27  * |-------------------------------------------|
28  * |producer index (4 bytes)                   |
29  * |consumer index (4 bytes)                   |
30  * |element size (4 bytes)                     |
31  * |element count (4 bytes)                    |
32  * |===========================================|
33  * |Fw to Host Queue info (16 bytes)           |
34  * |-------------------------------------------|
35  * |producer index (4 bytes)                   |
36  * |consumer index (4 bytes)                   |
37  * |element size (4 bytes)                     |
38  * |element count (4 bytes)                    |
39  * |===========================================|
40  * |Host to Fw Queue                           |
41  * |-------------------------------------------|
42  * |((elem_sz + hdr(8 bytes)) * elem_cnt) bytes|
43  * |===========================================|
44  * |===========================================|
45  * |Fw to Host Queue                           |
46  * |-------------------------------------------|
47  * |((elem_sz + hdr(8 bytes)) * elem_cnt) bytes|
48  * |===========================================|
49  */
50 
51 #define OCTEP_CTRL_MBOX_MAGIC_NUMBER			0xdeaddeadbeefbeefull
52 
53 /* Size of mbox info in bytes */
54 #define OCTEP_CTRL_MBOX_INFO_SZ				256
55 /* Size of mbox host to target queue info in bytes */
56 #define OCTEP_CTRL_MBOX_H2FQ_INFO_SZ			16
57 /* Size of mbox target to host queue info in bytes */
58 #define OCTEP_CTRL_MBOX_F2HQ_INFO_SZ			16
59 /* Size of mbox queue in bytes */
60 #define OCTEP_CTRL_MBOX_Q_SZ(sz, cnt)			(((sz) + 8) * (cnt))
61 /* Size of mbox in bytes */
62 #define OCTEP_CTRL_MBOX_SZ(hsz, hcnt, fsz, fcnt)	(OCTEP_CTRL_MBOX_INFO_SZ + \
63 							 OCTEP_CTRL_MBOX_H2FQ_INFO_SZ + \
64 							 OCTEP_CTRL_MBOX_F2HQ_INFO_SZ + \
65 							 OCTEP_CTRL_MBOX_Q_SZ(hsz, hcnt) + \
66 							 OCTEP_CTRL_MBOX_Q_SZ(fsz, fcnt))
67 
68 /* Valid request message */
69 #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ		BIT(0)
70 /* Valid response message */
71 #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP		BIT(1)
72 /* Valid notification, no response required */
73 #define OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY		BIT(2)
74 
75 enum octep_ctrl_mbox_status {
76 	OCTEP_CTRL_MBOX_STATUS_INVALID = 0,
77 	OCTEP_CTRL_MBOX_STATUS_INIT,
78 	OCTEP_CTRL_MBOX_STATUS_READY,
79 	OCTEP_CTRL_MBOX_STATUS_UNINIT
80 };
81 
82 /* mbox message */
83 union octep_ctrl_mbox_msg_hdr {
84 	u64 word0;
85 	struct {
86 		/* OCTEP_CTRL_MBOX_MSG_HDR_FLAG_* */
87 		u32 flags;
88 		/* size of message in words excluding header */
89 		u32 sizew;
90 	};
91 };
92 
93 /* mbox message */
94 struct octep_ctrl_mbox_msg {
95 	/* mbox transaction header */
96 	union octep_ctrl_mbox_msg_hdr hdr;
97 	/* pointer to message buffer */
98 	void *msg;
99 };
100 
101 /* Mbox queue */
102 struct octep_ctrl_mbox_q {
103 	/* q element size, should be aligned to unsigned long */
104 	u16 elem_sz;
105 	/* q element count, should be power of 2 */
106 	u16 elem_cnt;
107 	/* q mask */
108 	u16 mask;
109 	/* producer address in bar mem */
110 	void __iomem *hw_prod;
111 	/* consumer address in bar mem */
112 	void __iomem *hw_cons;
113 	/* q base address in bar mem */
114 	void __iomem *hw_q;
115 };
116 
117 struct octep_ctrl_mbox {
118 	/* host driver version */
119 	u64 version;
120 	/* size of bar memory */
121 	u32 barmem_sz;
122 	/* pointer to BAR memory */
123 	void __iomem *barmem;
124 	/* user context for callback, can be null */
125 	void *user_ctx;
126 	/* callback handler for processing request, called from octep_ctrl_mbox_recv */
127 	int (*process_req)(void *user_ctx, struct octep_ctrl_mbox_msg *msg);
128 	/* host-to-fw queue */
129 	struct octep_ctrl_mbox_q h2fq;
130 	/* fw-to-host queue */
131 	struct octep_ctrl_mbox_q f2hq;
132 	/* lock for h2fq */
133 	struct mutex h2fq_lock;
134 	/* lock for f2hq */
135 	struct mutex f2hq_lock;
136 };
137 
138 /* Initialize control mbox.
139  *
140  * @param mbox: non-null pointer to struct octep_ctrl_mbox.
141  *
142  * return value: 0 on success, -errno on failure.
143  */
144 int octep_ctrl_mbox_init(struct octep_ctrl_mbox *mbox);
145 
146 /* Send mbox message.
147  *
148  * @param mbox: non-null pointer to struct octep_ctrl_mbox.
149  *
150  * return value: 0 on success, -errno on failure.
151  */
152 int octep_ctrl_mbox_send(struct octep_ctrl_mbox *mbox, struct octep_ctrl_mbox_msg *msg);
153 
154 /* Retrieve mbox message.
155  *
156  * @param mbox: non-null pointer to struct octep_ctrl_mbox.
157  *
158  * return value: 0 on success, -errno on failure.
159  */
160 int octep_ctrl_mbox_recv(struct octep_ctrl_mbox *mbox, struct octep_ctrl_mbox_msg *msg);
161 
162 /* Uninitialize control mbox.
163  *
164  * @param ep: non-null pointer to struct octep_ctrl_mbox.
165  *
166  * return value: 0 on success, -errno on failure.
167  */
168 int octep_ctrl_mbox_uninit(struct octep_ctrl_mbox *mbox);
169 
170 #endif /* __OCTEP_CTRL_MBOX_H__ */
171