xref: /linux/drivers/net/ethernet/mucse/rnpgbe/rnpgbe_mbx.c (revision 24f171c7e145f43b9f187578e89b0982ce87e54c)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2022 - 2025 Mucse Corporation. */
3 
4 #include <linux/errno.h>
5 #include <linux/bitfield.h>
6 #include <linux/iopoll.h>
7 
8 #include "rnpgbe_mbx.h"
9 
10 /**
11  * mbx_data_rd32 - Reads reg with base mbx->fwpf_shm_base
12  * @mbx: pointer to the MBX structure
13  * @reg: register offset
14  *
15  * Return: register value
16  **/
17 static u32 mbx_data_rd32(struct mucse_mbx_info *mbx, u32 reg)
18 {
19 	struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx);
20 
21 	return readl(hw->hw_addr + mbx->fwpf_shm_base + reg);
22 }
23 
24 /**
25  * mbx_data_wr32 - Writes value to reg with base mbx->fwpf_shm_base
26  * @mbx: pointer to the MBX structure
27  * @reg: register offset
28  * @value: value to be written
29  *
30  **/
31 static void mbx_data_wr32(struct mucse_mbx_info *mbx, u32 reg, u32 value)
32 {
33 	struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx);
34 
35 	writel(value, hw->hw_addr + mbx->fwpf_shm_base + reg);
36 }
37 
38 /**
39  * mbx_ctrl_rd32 - Reads reg with base mbx->fwpf_ctrl_base
40  * @mbx: pointer to the MBX structure
41  * @reg: register offset
42  *
43  * Return: register value
44  **/
45 static u32 mbx_ctrl_rd32(struct mucse_mbx_info *mbx, u32 reg)
46 {
47 	struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx);
48 
49 	return readl(hw->hw_addr + mbx->fwpf_ctrl_base + reg);
50 }
51 
52 /**
53  * mbx_ctrl_wr32 - Writes value to reg with base mbx->fwpf_ctrl_base
54  * @mbx: pointer to the MBX structure
55  * @reg: register offset
56  * @value: value to be written
57  *
58  **/
59 static void mbx_ctrl_wr32(struct mucse_mbx_info *mbx, u32 reg, u32 value)
60 {
61 	struct mucse_hw *hw = container_of(mbx, struct mucse_hw, mbx);
62 
63 	writel(value, hw->hw_addr + mbx->fwpf_ctrl_base + reg);
64 }
65 
66 /**
67  * mucse_mbx_get_lock_pf - Write ctrl and read back lock status
68  * @hw: pointer to the HW structure
69  *
70  * Return: register value after write
71  **/
72 static u32 mucse_mbx_get_lock_pf(struct mucse_hw *hw)
73 {
74 	struct mucse_mbx_info *mbx = &hw->mbx;
75 	u32 reg = MUCSE_MBX_PF2FW_CTRL(mbx);
76 
77 	mbx_ctrl_wr32(mbx, reg, MUCSE_MBX_PFU);
78 
79 	return mbx_ctrl_rd32(mbx, reg);
80 }
81 
82 /**
83  * mucse_obtain_mbx_lock_pf - Obtain mailbox lock
84  * @hw: pointer to the HW structure
85  *
86  * Pair with mucse_release_mbx_lock_pf()
87  * This function maybe used in an irq handler.
88  *
89  * Return: 0 on success, negative errno on failure
90  **/
91 static int mucse_obtain_mbx_lock_pf(struct mucse_hw *hw)
92 {
93 	struct mucse_mbx_info *mbx = &hw->mbx;
94 	u32 val;
95 
96 	return read_poll_timeout_atomic(mucse_mbx_get_lock_pf,
97 					val, val & MUCSE_MBX_PFU,
98 					mbx->delay_us,
99 					mbx->timeout_us,
100 					false, hw);
101 }
102 
103 /**
104  * mucse_release_mbx_lock_pf - Release mailbox lock
105  * @hw: pointer to the HW structure
106  * @req: send a request or not
107  *
108  * Pair with mucse_obtain_mbx_lock_pf():
109  * - Releases the mailbox lock by clearing MUCSE_MBX_PFU bit
110  * - Simultaneously sends the request by setting MUCSE_MBX_REQ bit
111  *   if req is true
112  * (Both bits are in the same mailbox control register,
113  * so operations are combined)
114  **/
115 static void mucse_release_mbx_lock_pf(struct mucse_hw *hw, bool req)
116 {
117 	struct mucse_mbx_info *mbx = &hw->mbx;
118 	u32 reg = MUCSE_MBX_PF2FW_CTRL(mbx);
119 
120 	mbx_ctrl_wr32(mbx, reg, req ? MUCSE_MBX_REQ : 0);
121 }
122 
123 /**
124  * mucse_mbx_get_fwreq - Read fw req from reg
125  * @mbx: pointer to the mbx structure
126  *
127  * Return: the fwreq value
128  **/
129 static u16 mucse_mbx_get_fwreq(struct mucse_mbx_info *mbx)
130 {
131 	u32 val = mbx_data_rd32(mbx, MUCSE_MBX_FW2PF_CNT);
132 
133 	return FIELD_GET(GENMASK_U32(15, 0), val);
134 }
135 
136 /**
137  * mucse_mbx_inc_pf_ack - Increase ack
138  * @hw: pointer to the HW structure
139  *
140  * mucse_mbx_inc_pf_ack reads pf_ack from hw, then writes
141  * new value back after increase
142  **/
143 static void mucse_mbx_inc_pf_ack(struct mucse_hw *hw)
144 {
145 	struct mucse_mbx_info *mbx = &hw->mbx;
146 	u16 ack;
147 	u32 val;
148 
149 	val = mbx_data_rd32(mbx, MUCSE_MBX_PF2FW_CNT);
150 	ack = FIELD_GET(GENMASK_U32(31, 16), val);
151 	ack++;
152 	val &= ~GENMASK_U32(31, 16);
153 	val |= FIELD_PREP(GENMASK_U32(31, 16), ack);
154 	mbx_data_wr32(mbx, MUCSE_MBX_PF2FW_CNT, val);
155 }
156 
157 /**
158  * mucse_read_mbx_pf - Read a message from the mailbox
159  * @hw: pointer to the HW structure
160  * @msg: the message buffer
161  * @size: length of buffer
162  *
163  * mucse_read_mbx_pf copies a message from the mbx buffer to the caller's
164  * memory buffer. The presumption is that the caller knows that there was
165  * a message due to a fw request so no polling for message is needed.
166  *
167  * Return: 0 on success, negative errno on failure
168  **/
169 static int mucse_read_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
170 {
171 	const int size_in_words = size / sizeof(u32);
172 	struct mucse_mbx_info *mbx = &hw->mbx;
173 	int err;
174 
175 	err = mucse_obtain_mbx_lock_pf(hw);
176 	if (err)
177 		return err;
178 
179 	for (int i = 0; i < size_in_words; i++)
180 		msg[i] = mbx_data_rd32(mbx, MUCSE_MBX_FWPF_SHM + 4 * i);
181 	/* Hw needs write data_reg at last */
182 	mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM, 0);
183 	/* flush reqs as we have read this request data */
184 	hw->mbx.fw_req = mucse_mbx_get_fwreq(mbx);
185 	mucse_mbx_inc_pf_ack(hw);
186 	mucse_release_mbx_lock_pf(hw, false);
187 
188 	return 0;
189 }
190 
191 /**
192  * mucse_check_for_msg_pf - Check to see if the fw has sent mail
193  * @hw: pointer to the HW structure
194  *
195  * Return: 0 if the fw has set the Status bit or else -EIO
196  **/
197 static int mucse_check_for_msg_pf(struct mucse_hw *hw)
198 {
199 	struct mucse_mbx_info *mbx = &hw->mbx;
200 	u16 fw_req;
201 
202 	fw_req = mucse_mbx_get_fwreq(mbx);
203 	/* chip's register is reset to 0 when rc send reset
204 	 * mbx command. Return -EIO if in this state, others
205 	 * fw == hw->mbx.fw_req means no new msg.
206 	 **/
207 	if (fw_req == 0 || fw_req == hw->mbx.fw_req)
208 		return -EIO;
209 
210 	return 0;
211 }
212 
213 /**
214  * mucse_poll_for_msg - Wait for message notification
215  * @hw: pointer to the HW structure
216  *
217  * Return: 0 on success, negative errno on failure
218  **/
219 static int mucse_poll_for_msg(struct mucse_hw *hw)
220 {
221 	struct mucse_mbx_info *mbx = &hw->mbx;
222 	int val;
223 
224 	return read_poll_timeout(mucse_check_for_msg_pf,
225 				 val, !val, mbx->delay_us,
226 				 mbx->timeout_us,
227 				 false, hw);
228 }
229 
230 /**
231  * mucse_poll_and_read_mbx - Wait for message notification and receive message
232  * @hw: pointer to the HW structure
233  * @msg: the message buffer
234  * @size: length of buffer
235  *
236  * Return: 0 if it successfully received a message notification and
237  * copied it into the receive buffer, negative errno on failure
238  **/
239 int mucse_poll_and_read_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
240 {
241 	int err;
242 
243 	err = mucse_poll_for_msg(hw);
244 	if (err)
245 		return err;
246 
247 	return mucse_read_mbx_pf(hw, msg, size);
248 }
249 
250 /**
251  * mucse_mbx_get_fwack - Read fw ack from reg
252  * @mbx: pointer to the MBX structure
253  *
254  * Return: the fwack value
255  **/
256 static u16 mucse_mbx_get_fwack(struct mucse_mbx_info *mbx)
257 {
258 	u32 val = mbx_data_rd32(mbx, MUCSE_MBX_FW2PF_CNT);
259 
260 	return FIELD_GET(GENMASK_U32(31, 16), val);
261 }
262 
263 /**
264  * mucse_mbx_inc_pf_req - Increase req
265  * @hw: pointer to the HW structure
266  *
267  * mucse_mbx_inc_pf_req reads pf_req from hw, then writes
268  * new value back after increase
269  **/
270 static void mucse_mbx_inc_pf_req(struct mucse_hw *hw)
271 {
272 	struct mucse_mbx_info *mbx = &hw->mbx;
273 	u16 req;
274 	u32 val;
275 
276 	val = mbx_data_rd32(mbx, MUCSE_MBX_PF2FW_CNT);
277 	req = FIELD_GET(GENMASK_U32(15, 0), val);
278 	req++;
279 	val &= ~GENMASK_U32(15, 0);
280 	val |= FIELD_PREP(GENMASK_U32(15, 0), req);
281 	mbx_data_wr32(mbx, MUCSE_MBX_PF2FW_CNT, val);
282 }
283 
284 /**
285  * mucse_write_mbx_pf - Place a message in the mailbox
286  * @hw: pointer to the HW structure
287  * @msg: the message buffer
288  * @size: length of buffer
289  *
290  * Return: 0 if it successfully copied message into the buffer,
291  * negative errno on failure
292  **/
293 static int mucse_write_mbx_pf(struct mucse_hw *hw, u32 *msg, u16 size)
294 {
295 	const int size_in_words = size / sizeof(u32);
296 	struct mucse_mbx_info *mbx = &hw->mbx;
297 	int err;
298 
299 	err = mucse_obtain_mbx_lock_pf(hw);
300 	if (err)
301 		return err;
302 
303 	for (int i = 0; i < size_in_words; i++)
304 		mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM + i * 4, msg[i]);
305 
306 	/* flush acks as we are overwriting the message buffer */
307 	hw->mbx.fw_ack = mucse_mbx_get_fwack(mbx);
308 	mucse_mbx_inc_pf_req(hw);
309 	mucse_release_mbx_lock_pf(hw, true);
310 
311 	return 0;
312 }
313 
314 /**
315  * mucse_check_for_ack_pf - Check to see if the fw has ACKed
316  * @hw: pointer to the HW structure
317  *
318  * Return: 0 if the fw has set the Status bit or else -EIO
319  **/
320 static int mucse_check_for_ack_pf(struct mucse_hw *hw)
321 {
322 	struct mucse_mbx_info *mbx = &hw->mbx;
323 	u16 fw_ack;
324 
325 	fw_ack = mucse_mbx_get_fwack(mbx);
326 	/* chip's register is reset to 0 when rc send reset
327 	 * mbx command. Return -EIO if in this state, others
328 	 * fw_ack == hw->mbx.fw_ack means no new ack.
329 	 **/
330 	if (fw_ack == 0 || fw_ack == hw->mbx.fw_ack)
331 		return -EIO;
332 
333 	return 0;
334 }
335 
336 /**
337  * mucse_poll_for_ack - Wait for message acknowledgment
338  * @hw: pointer to the HW structure
339  *
340  * Return: 0 if it successfully received a message acknowledgment,
341  * else negative errno
342  **/
343 static int mucse_poll_for_ack(struct mucse_hw *hw)
344 {
345 	struct mucse_mbx_info *mbx = &hw->mbx;
346 	int val;
347 
348 	return read_poll_timeout(mucse_check_for_ack_pf,
349 				 val, !val, mbx->delay_us,
350 				 mbx->timeout_us,
351 				 false, hw);
352 }
353 
354 /**
355  * mucse_write_and_wait_ack_mbx - Write a message to the mailbox, wait for ack
356  * @hw: pointer to the HW structure
357  * @msg: the message buffer
358  * @size: length of buffer
359  *
360  * Return: 0 if it successfully copied message into the buffer and
361  * received an ack to that message within delay * timeout_cnt period
362  **/
363 int mucse_write_and_wait_ack_mbx(struct mucse_hw *hw, u32 *msg, u16 size)
364 {
365 	int err;
366 
367 	err = mucse_write_mbx_pf(hw, msg, size);
368 	if (err)
369 		return err;
370 
371 	return mucse_poll_for_ack(hw);
372 }
373 
374 /**
375  * mucse_mbx_reset - Reset mbx info, sync info from regs
376  * @hw: pointer to the HW structure
377  *
378  * mucse_mbx_reset resets all mbx variables to default.
379  **/
380 static void mucse_mbx_reset(struct mucse_hw *hw)
381 {
382 	struct mucse_mbx_info *mbx = &hw->mbx;
383 	u32 val;
384 
385 	val = mbx_data_rd32(mbx, MUCSE_MBX_FW2PF_CNT);
386 	hw->mbx.fw_req = FIELD_GET(GENMASK_U32(15, 0), val);
387 	hw->mbx.fw_ack = FIELD_GET(GENMASK_U32(31, 16), val);
388 	mbx_ctrl_wr32(mbx, MUCSE_MBX_PF2FW_CTRL(mbx), 0);
389 	mbx_ctrl_wr32(mbx, MUCSE_MBX_FWPF_MASK(mbx), GENMASK_U32(31, 16));
390 }
391 
392 /**
393  * mucse_init_mbx_params_pf - Set initial values for pf mailbox
394  * @hw: pointer to the HW structure
395  *
396  * Initializes the hw->mbx struct to correct values for pf mailbox
397  */
398 void mucse_init_mbx_params_pf(struct mucse_hw *hw)
399 {
400 	struct mucse_mbx_info *mbx = &hw->mbx;
401 
402 	mbx->delay_us = 100;
403 	mbx->timeout_us = 4 * USEC_PER_SEC;
404 	mutex_init(&mbx->lock);
405 	mucse_mbx_reset(hw);
406 }
407