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 **/
mbx_data_rd32(struct mucse_mbx_info * mbx,u32 reg)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 **/
mbx_data_wr32(struct mucse_mbx_info * mbx,u32 reg,u32 value)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 **/
mbx_ctrl_rd32(struct mucse_mbx_info * mbx,u32 reg)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 **/
mbx_ctrl_wr32(struct mucse_mbx_info * mbx,u32 reg,u32 value)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 **/
mucse_mbx_get_lock_pf(struct mucse_hw * hw)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 **/
mucse_obtain_mbx_lock_pf(struct mucse_hw * hw)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 **/
mucse_release_mbx_lock_pf(struct mucse_hw * hw,bool req)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 **/
mucse_mbx_get_fwreq(struct mucse_mbx_info * mbx)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 **/
mucse_mbx_inc_pf_ack(struct mucse_hw * hw)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 **/
mucse_read_mbx_pf(struct mucse_hw * hw,__le32 * msg,u16 size)169 static int mucse_read_mbx_pf(struct mucse_hw *hw, __le32 *msg, u16 size)
170 {
171 const int size_in_words = size / sizeof(__le32);
172 struct mucse_mbx_info *mbx = &hw->mbx;
173 int off = MUCSE_MBX_FWPF_SHM;
174 int err;
175
176 err = mucse_obtain_mbx_lock_pf(hw);
177 if (err)
178 return err;
179
180 /* memcpy_fromio() is unsuitable: the mailbox uses 32-bit MMIO
181 * registers, not byte-addressable RAM. readl() guarantees
182 * the required 32-bit access width.
183 */
184 for (int i = 0; i < size_in_words; i++)
185 msg[i] = cpu_to_le32(mbx_data_rd32(mbx, off + 4 * i));
186 /* Hw needs write data_reg at last */
187 mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM, 0);
188 /* flush reqs as we have read this request data */
189 hw->mbx.fw_req = mucse_mbx_get_fwreq(mbx);
190 mucse_mbx_inc_pf_ack(hw);
191 mucse_release_mbx_lock_pf(hw, false);
192
193 return 0;
194 }
195
196 /**
197 * mucse_check_for_msg_pf - Check to see if the fw has sent mail
198 * @hw: pointer to the HW structure
199 *
200 * Return: 0 if the fw has set the Status bit or else -EIO
201 **/
mucse_check_for_msg_pf(struct mucse_hw * hw)202 static int mucse_check_for_msg_pf(struct mucse_hw *hw)
203 {
204 struct mucse_mbx_info *mbx = &hw->mbx;
205 u16 fw_req;
206
207 fw_req = mucse_mbx_get_fwreq(mbx);
208 /* chip's register is reset to 0 when rc send reset
209 * mbx command. Return -EIO if in this state, others
210 * fw == hw->mbx.fw_req means no new msg.
211 **/
212 if (fw_req == 0 || fw_req == hw->mbx.fw_req)
213 return -EIO;
214
215 return 0;
216 }
217
218 /**
219 * mucse_poll_for_msg - Wait for message notification
220 * @hw: pointer to the HW structure
221 *
222 * Return: 0 on success, negative errno on failure
223 **/
mucse_poll_for_msg(struct mucse_hw * hw)224 static int mucse_poll_for_msg(struct mucse_hw *hw)
225 {
226 struct mucse_mbx_info *mbx = &hw->mbx;
227 int val;
228
229 return read_poll_timeout(mucse_check_for_msg_pf,
230 val, !val, mbx->delay_us,
231 mbx->timeout_us,
232 false, hw);
233 }
234
235 /**
236 * mucse_poll_and_read_mbx - Wait for message notification and receive message
237 * @hw: pointer to the HW structure
238 * @msg: the message buffer
239 * @size: length of buffer
240 *
241 * Return: 0 if it successfully received a message notification and
242 * copied it into the receive buffer, negative errno on failure
243 **/
mucse_poll_and_read_mbx(struct mucse_hw * hw,__le32 * msg,u16 size)244 int mucse_poll_and_read_mbx(struct mucse_hw *hw, __le32 *msg, u16 size)
245 {
246 int err;
247
248 err = mucse_poll_for_msg(hw);
249 if (err)
250 return err;
251
252 return mucse_read_mbx_pf(hw, msg, size);
253 }
254
255 /**
256 * mucse_mbx_get_fwack - Read fw ack from reg
257 * @mbx: pointer to the MBX structure
258 *
259 * Return: the fwack value
260 **/
mucse_mbx_get_fwack(struct mucse_mbx_info * mbx)261 static u16 mucse_mbx_get_fwack(struct mucse_mbx_info *mbx)
262 {
263 u32 val = mbx_data_rd32(mbx, MUCSE_MBX_FW2PF_CNT);
264
265 return FIELD_GET(GENMASK_U32(31, 16), val);
266 }
267
268 /**
269 * mucse_mbx_inc_pf_req - Increase req
270 * @hw: pointer to the HW structure
271 *
272 * mucse_mbx_inc_pf_req reads pf_req from hw, then writes
273 * new value back after increase
274 **/
mucse_mbx_inc_pf_req(struct mucse_hw * hw)275 static void mucse_mbx_inc_pf_req(struct mucse_hw *hw)
276 {
277 struct mucse_mbx_info *mbx = &hw->mbx;
278 u16 req;
279 u32 val;
280
281 val = mbx_data_rd32(mbx, MUCSE_MBX_PF2FW_CNT);
282 req = FIELD_GET(GENMASK_U32(15, 0), val);
283 req++;
284 val &= ~GENMASK_U32(15, 0);
285 val |= FIELD_PREP(GENMASK_U32(15, 0), req);
286 mbx_data_wr32(mbx, MUCSE_MBX_PF2FW_CNT, val);
287 }
288
289 /**
290 * mucse_write_mbx_pf - Place a message in the mailbox
291 * @hw: pointer to the HW structure
292 * @msg: the message buffer
293 * @size: length of buffer
294 *
295 * Return: 0 if it successfully copied message into the buffer,
296 * negative errno on failure
297 **/
mucse_write_mbx_pf(struct mucse_hw * hw,const __le32 * msg,u16 size)298 static int mucse_write_mbx_pf(struct mucse_hw *hw, const __le32 *msg, u16 size)
299 {
300 const int size_in_words = size / sizeof(__le32);
301 struct mucse_mbx_info *mbx = &hw->mbx;
302 int err;
303
304 err = mucse_obtain_mbx_lock_pf(hw);
305 if (err)
306 return err;
307
308 /* memcpy_toio() would decompose into arbitrary-width accesses;
309 * the mailbox requires 32-bit MMIO writes via writel().
310 */
311 for (int i = 0; i < size_in_words; i++)
312 mbx_data_wr32(mbx, MUCSE_MBX_FWPF_SHM + i * 4,
313 le32_to_cpu(msg[i]));
314
315 /* flush acks as we are overwriting the message buffer */
316 hw->mbx.fw_ack = mucse_mbx_get_fwack(mbx);
317 mucse_mbx_inc_pf_req(hw);
318 mucse_release_mbx_lock_pf(hw, true);
319
320 return 0;
321 }
322
323 /**
324 * mucse_check_for_ack_pf - Check to see if the fw has ACKed
325 * @hw: pointer to the HW structure
326 *
327 * Return: 0 if the fw has set the Status bit or else -EIO
328 **/
mucse_check_for_ack_pf(struct mucse_hw * hw)329 static int mucse_check_for_ack_pf(struct mucse_hw *hw)
330 {
331 struct mucse_mbx_info *mbx = &hw->mbx;
332 u16 fw_ack;
333
334 fw_ack = mucse_mbx_get_fwack(mbx);
335 /* chip's register is reset to 0 when rc send reset
336 * mbx command. Return -EIO if in this state, others
337 * fw_ack == hw->mbx.fw_ack means no new ack.
338 **/
339 if (fw_ack == 0 || fw_ack == hw->mbx.fw_ack)
340 return -EIO;
341
342 return 0;
343 }
344
345 /**
346 * mucse_poll_for_ack - Wait for message acknowledgment
347 * @hw: pointer to the HW structure
348 *
349 * Return: 0 if it successfully received a message acknowledgment,
350 * else negative errno
351 **/
mucse_poll_for_ack(struct mucse_hw * hw)352 static int mucse_poll_for_ack(struct mucse_hw *hw)
353 {
354 struct mucse_mbx_info *mbx = &hw->mbx;
355 int val;
356
357 return read_poll_timeout(mucse_check_for_ack_pf,
358 val, !val, mbx->delay_us,
359 mbx->timeout_us,
360 false, hw);
361 }
362
363 /**
364 * mucse_write_and_wait_ack_mbx - Write a message to the mailbox, wait for ack
365 * @hw: pointer to the HW structure
366 * @msg: the message buffer
367 * @size: length of buffer
368 *
369 * Return: 0 if it successfully copied message into the buffer and
370 * received an ack to that message within delay * timeout_cnt period
371 **/
mucse_write_and_wait_ack_mbx(struct mucse_hw * hw,const __le32 * msg,u16 size)372 int mucse_write_and_wait_ack_mbx(struct mucse_hw *hw, const __le32 *msg,
373 u16 size)
374 {
375 int err;
376
377 err = mucse_write_mbx_pf(hw, msg, size);
378 if (err)
379 return err;
380
381 return mucse_poll_for_ack(hw);
382 }
383
384 /**
385 * mucse_mbx_reset - Reset mbx info, sync info from regs
386 * @hw: pointer to the HW structure
387 *
388 * mucse_mbx_reset resets all mbx variables to default.
389 **/
mucse_mbx_reset(struct mucse_hw * hw)390 static void mucse_mbx_reset(struct mucse_hw *hw)
391 {
392 struct mucse_mbx_info *mbx = &hw->mbx;
393 u32 val;
394
395 val = mbx_data_rd32(mbx, MUCSE_MBX_FW2PF_CNT);
396 hw->mbx.fw_req = FIELD_GET(GENMASK_U32(15, 0), val);
397 hw->mbx.fw_ack = FIELD_GET(GENMASK_U32(31, 16), val);
398 mbx_ctrl_wr32(mbx, MUCSE_MBX_PF2FW_CTRL(mbx), 0);
399 mbx_ctrl_wr32(mbx, MUCSE_MBX_FWPF_MASK(mbx), GENMASK_U32(31, 16));
400 }
401
402 /**
403 * mucse_init_mbx_params_pf - Set initial values for pf mailbox
404 * @hw: pointer to the HW structure
405 *
406 * Initializes the hw->mbx struct to correct values for pf mailbox
407 */
mucse_init_mbx_params_pf(struct mucse_hw * hw)408 void mucse_init_mbx_params_pf(struct mucse_hw *hw)
409 {
410 struct mucse_mbx_info *mbx = &hw->mbx;
411
412 mbx->delay_us = 100;
413 mbx->timeout_us = 4 * USEC_PER_SEC;
414 mutex_init(&mbx->lock);
415 mucse_mbx_reset(hw);
416 }
417