xref: /linux/drivers/net/ethernet/intel/ixgbevf/mbx.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 1999 - 2018 Intel Corporation. */
3 
4 #include "mbx.h"
5 #include "ixgbevf.h"
6 
7 /**
8  *  ixgbevf_poll_for_msg - Wait for message notification
9  *  @hw: pointer to the HW structure
10  *
11  *  returns 0 if it successfully received a message notification
12  **/
ixgbevf_poll_for_msg(struct ixgbe_hw * hw)13 static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw)
14 {
15 	struct ixgbe_mbx_info *mbx = &hw->mbx;
16 	int countdown = mbx->timeout;
17 
18 	if (!countdown || !mbx->ops.check_for_msg)
19 		return IXGBE_ERR_CONFIG;
20 
21 	while (countdown && mbx->ops.check_for_msg(hw)) {
22 		countdown--;
23 		udelay(mbx->udelay);
24 	}
25 
26 	return countdown ? 0 : IXGBE_ERR_TIMEOUT;
27 }
28 
29 /**
30  *  ixgbevf_poll_for_ack - Wait for message acknowledgment
31  *  @hw: pointer to the HW structure
32  *
33  *  returns 0 if it successfully received a message acknowledgment
34  **/
ixgbevf_poll_for_ack(struct ixgbe_hw * hw)35 static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw)
36 {
37 	struct ixgbe_mbx_info *mbx = &hw->mbx;
38 	int countdown = mbx->timeout;
39 
40 	if (!countdown || !mbx->ops.check_for_ack)
41 		return IXGBE_ERR_CONFIG;
42 
43 	while (countdown && mbx->ops.check_for_ack(hw)) {
44 		countdown--;
45 		udelay(mbx->udelay);
46 	}
47 
48 	return countdown ? 0 : IXGBE_ERR_TIMEOUT;
49 }
50 
51 /**
52  * ixgbevf_read_mailbox_vf - read VF's mailbox register
53  * @hw: pointer to the HW structure
54  *
55  * This function is used to read the mailbox register dedicated for VF without
56  * losing the read to clear status bits.
57  **/
ixgbevf_read_mailbox_vf(struct ixgbe_hw * hw)58 static u32 ixgbevf_read_mailbox_vf(struct ixgbe_hw *hw)
59 {
60 	u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
61 
62 	vf_mailbox |= hw->mbx.vf_mailbox;
63 	hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
64 
65 	return vf_mailbox;
66 }
67 
68 /**
69  * ixgbevf_clear_msg_vf - clear PF status bit
70  * @hw: pointer to the HW structure
71  *
72  * This function is used to clear PFSTS bit in the VFMAILBOX register
73  **/
ixgbevf_clear_msg_vf(struct ixgbe_hw * hw)74 static void ixgbevf_clear_msg_vf(struct ixgbe_hw *hw)
75 {
76 	u32 vf_mailbox = ixgbevf_read_mailbox_vf(hw);
77 
78 	if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
79 		hw->mbx.stats.reqs++;
80 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
81 	}
82 }
83 
84 /**
85  * ixgbevf_clear_ack_vf - clear PF ACK bit
86  * @hw: pointer to the HW structure
87  *
88  * This function is used to clear PFACK bit in the VFMAILBOX register
89  **/
ixgbevf_clear_ack_vf(struct ixgbe_hw * hw)90 static void ixgbevf_clear_ack_vf(struct ixgbe_hw *hw)
91 {
92 	u32 vf_mailbox = ixgbevf_read_mailbox_vf(hw);
93 
94 	if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
95 		hw->mbx.stats.acks++;
96 		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
97 	}
98 }
99 
100 /**
101  * ixgbevf_clear_rst_vf - clear PF reset bit
102  * @hw: pointer to the HW structure
103  *
104  * This function is used to clear reset indication and reset done bit in
105  * VFMAILBOX register after reset the shared resources and the reset sequence.
106  **/
ixgbevf_clear_rst_vf(struct ixgbe_hw * hw)107 static void ixgbevf_clear_rst_vf(struct ixgbe_hw *hw)
108 {
109 	u32 vf_mailbox = ixgbevf_read_mailbox_vf(hw);
110 
111 	if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
112 		hw->mbx.stats.rsts++;
113 		hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
114 					IXGBE_VFMAILBOX_RSTD);
115 	}
116 }
117 
118 /**
119  *  ixgbevf_check_for_bit_vf - Determine if a status bit was set
120  *  @hw: pointer to the HW structure
121  *  @mask: bitmask for bits to be tested and cleared
122  *
123  *  This function is used to check for the read to clear bits within
124  *  the V2P mailbox.
125  **/
ixgbevf_check_for_bit_vf(struct ixgbe_hw * hw,u32 mask)126 static s32 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
127 {
128 	u32 vf_mailbox = ixgbevf_read_mailbox_vf(hw);
129 	s32 ret_val = IXGBE_ERR_MBX;
130 
131 	if (vf_mailbox & mask)
132 		ret_val = 0;
133 
134 	return ret_val;
135 }
136 
137 /**
138  *  ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail
139  *  @hw: pointer to the HW structure
140  *
141  *  returns 0 if the PF has set the Status bit or else ERR_MBX
142  **/
ixgbevf_check_for_msg_vf(struct ixgbe_hw * hw)143 static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw)
144 {
145 	s32 ret_val = IXGBE_ERR_MBX;
146 
147 	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
148 		ret_val = 0;
149 		hw->mbx.stats.reqs++;
150 	}
151 
152 	return ret_val;
153 }
154 
155 /**
156  *  ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd
157  *  @hw: pointer to the HW structure
158  *
159  *  returns 0 if the PF has set the ACK bit or else ERR_MBX
160  **/
ixgbevf_check_for_ack_vf(struct ixgbe_hw * hw)161 static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw)
162 {
163 	s32 ret_val = IXGBE_ERR_MBX;
164 
165 	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
166 		ret_val = 0;
167 		ixgbevf_clear_ack_vf(hw);
168 		hw->mbx.stats.acks++;
169 	}
170 
171 	return ret_val;
172 }
173 
174 /**
175  *  ixgbevf_check_for_rst_vf - checks to see if the PF has reset
176  *  @hw: pointer to the HW structure
177  *
178  *  returns true if the PF has set the reset done bit or else false
179  **/
ixgbevf_check_for_rst_vf(struct ixgbe_hw * hw)180 static s32 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw)
181 {
182 	s32 ret_val = IXGBE_ERR_MBX;
183 
184 	if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
185 					   IXGBE_VFMAILBOX_RSTI))) {
186 		ret_val = 0;
187 		ixgbevf_clear_rst_vf(hw);
188 		hw->mbx.stats.rsts++;
189 	}
190 
191 	return ret_val;
192 }
193 
194 /**
195  *  ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock
196  *  @hw: pointer to the HW structure
197  *
198  *  return 0 if we obtained the mailbox lock
199  **/
ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw * hw)200 static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
201 {
202 	struct ixgbe_mbx_info *mbx = &hw->mbx;
203 	s32 ret_val = IXGBE_ERR_CONFIG;
204 	int countdown = mbx->timeout;
205 	u32 vf_mailbox;
206 
207 	if (!mbx->timeout)
208 		return ret_val;
209 
210 	while (countdown--) {
211 		/* Reserve mailbox for VF use */
212 		vf_mailbox = ixgbevf_read_mailbox_vf(hw);
213 		vf_mailbox |= IXGBE_VFMAILBOX_VFU;
214 		IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
215 
216 		/* Verify that VF is the owner of the lock */
217 		if (ixgbevf_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
218 			ret_val = 0;
219 			break;
220 		}
221 
222 		/* Wait a bit before trying again */
223 		udelay(mbx->udelay);
224 	}
225 
226 	if (ret_val)
227 		ret_val = IXGBE_ERR_TIMEOUT;
228 
229 	return ret_val;
230 }
231 
232 /**
233  * ixgbevf_release_mbx_lock_vf - release mailbox lock
234  * @hw: pointer to the HW structure
235  **/
ixgbevf_release_mbx_lock_vf(struct ixgbe_hw * hw)236 static void ixgbevf_release_mbx_lock_vf(struct ixgbe_hw *hw)
237 {
238 	u32 vf_mailbox;
239 
240 	/* Return ownership of the buffer */
241 	vf_mailbox = ixgbevf_read_mailbox_vf(hw);
242 	vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
243 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
244 }
245 
246 /**
247  * ixgbevf_release_mbx_lock_vf_legacy - release mailbox lock
248  * @hw: pointer to the HW structure
249  **/
ixgbevf_release_mbx_lock_vf_legacy(struct ixgbe_hw * __always_unused hw)250 static void ixgbevf_release_mbx_lock_vf_legacy(struct ixgbe_hw *__always_unused hw)
251 {
252 }
253 
254 /**
255  *  ixgbevf_write_mbx_vf - Write a message to the mailbox
256  *  @hw: pointer to the HW structure
257  *  @msg: The message buffer
258  *  @size: Length of buffer
259  *
260  *  returns 0 if it successfully copied message into the buffer
261  **/
ixgbevf_write_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size)262 static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
263 {
264 	u32 vf_mailbox;
265 	s32 ret_val;
266 	u16 i;
267 
268 	/* lock the mailbox to prevent PF/VF race condition */
269 	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
270 	if (ret_val)
271 		goto out_no_write;
272 
273 	/* flush msg and acks as we are overwriting the message buffer */
274 	ixgbevf_clear_msg_vf(hw);
275 	ixgbevf_clear_ack_vf(hw);
276 
277 	/* copy the caller specified message to the mailbox memory buffer */
278 	for (i = 0; i < size; i++)
279 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
280 
281 	/* update stats */
282 	hw->mbx.stats.msgs_tx++;
283 
284 	/* interrupt the PF to tell it a message has been sent */
285 	vf_mailbox = ixgbevf_read_mailbox_vf(hw);
286 	vf_mailbox |= IXGBE_VFMAILBOX_REQ;
287 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
288 
289 	/* if msg sent wait until we receive an ack */
290 	ret_val = ixgbevf_poll_for_ack(hw);
291 
292 out_no_write:
293 	hw->mbx.ops.release(hw);
294 
295 	return ret_val;
296 }
297 
298 /**
299  *  ixgbevf_write_mbx_vf_legacy - Write a message to the mailbox
300  *  @hw: pointer to the HW structure
301  *  @msg: The message buffer
302  *  @size: Length of buffer
303  *
304  *  returns 0 if it successfully copied message into the buffer
305  **/
ixgbevf_write_mbx_vf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size)306 static s32 ixgbevf_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size)
307 {
308 	s32 ret_val;
309 	u16 i;
310 
311 	/* lock the mailbox to prevent PF/VF race condition */
312 	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
313 	if (ret_val)
314 		goto out_no_write;
315 
316 	/* flush msg and acks as we are overwriting the message buffer */
317 	ixgbevf_check_for_msg_vf(hw);
318 	ixgbevf_clear_msg_vf(hw);
319 	ixgbevf_check_for_ack_vf(hw);
320 	ixgbevf_clear_ack_vf(hw);
321 
322 	/* copy the caller specified message to the mailbox memory buffer */
323 	for (i = 0; i < size; i++)
324 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
325 
326 	/* update stats */
327 	hw->mbx.stats.msgs_tx++;
328 
329 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
330 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
331 
332 out_no_write:
333 	return ret_val;
334 }
335 
336 /**
337  *  ixgbevf_read_mbx_vf - Reads a message from the inbox intended for VF
338  *  @hw: pointer to the HW structure
339  *  @msg: The message buffer
340  *  @size: Length of buffer
341  *
342  *  returns 0 if it successfully read message from buffer
343  **/
ixgbevf_read_mbx_vf(struct ixgbe_hw * hw,u32 * msg,u16 size)344 static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)
345 {
346 	u32 vf_mailbox;
347 	s32 ret_val;
348 	u16 i;
349 
350 	/* check if there is a message from PF */
351 	ret_val = ixgbevf_check_for_msg_vf(hw);
352 	if (ret_val)
353 		return ret_val;
354 
355 	ixgbevf_clear_msg_vf(hw);
356 
357 	/* copy the message from the mailbox memory buffer */
358 	for (i = 0; i < size; i++)
359 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
360 
361 	/* Acknowledge receipt */
362 	vf_mailbox = ixgbevf_read_mailbox_vf(hw);
363 	vf_mailbox |= IXGBE_VFMAILBOX_ACK;
364 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
365 
366 	/* update stats */
367 	hw->mbx.stats.msgs_rx++;
368 
369 	return ret_val;
370 }
371 
372 /**
373  *  ixgbevf_read_mbx_vf_legacy - Reads a message from the inbox intended for VF
374  *  @hw: pointer to the HW structure
375  *  @msg: The message buffer
376  *  @size: Length of buffer
377  *
378  *  returns 0 if it successfully read message from buffer
379  **/
ixgbevf_read_mbx_vf_legacy(struct ixgbe_hw * hw,u32 * msg,u16 size)380 static s32 ixgbevf_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size)
381 {
382 	s32 ret_val = 0;
383 	u16 i;
384 
385 	/* lock the mailbox to prevent PF/VF race condition */
386 	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);
387 	if (ret_val)
388 		goto out_no_read;
389 
390 	/* copy the message from the mailbox memory buffer */
391 	for (i = 0; i < size; i++)
392 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
393 
394 	/* Acknowledge receipt and release mailbox, then we're done */
395 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
396 
397 	/* update stats */
398 	hw->mbx.stats.msgs_rx++;
399 
400 out_no_read:
401 	return ret_val;
402 }
403 
404 /**
405  *  ixgbevf_init_mbx_params_vf - set initial values for VF mailbox
406  *  @hw: pointer to the HW structure
407  *
408  *  Initializes the hw->mbx struct to correct values for VF mailbox
409  */
ixgbevf_init_mbx_params_vf(struct ixgbe_hw * hw)410 static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)
411 {
412 	struct ixgbe_mbx_info *mbx = &hw->mbx;
413 
414 	/* start mailbox as timed out and let the reset_hw call set the timeout
415 	 * value to begin communications
416 	 */
417 	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
418 	mbx->udelay = IXGBE_VF_MBX_INIT_DELAY;
419 
420 	mbx->size = IXGBE_VFMAILBOX_SIZE;
421 
422 	mbx->stats.msgs_tx = 0;
423 	mbx->stats.msgs_rx = 0;
424 	mbx->stats.reqs = 0;
425 	mbx->stats.acks = 0;
426 	mbx->stats.rsts = 0;
427 
428 	return 0;
429 }
430 
431 /**
432  * ixgbevf_poll_mbx - Wait for message and read it from the mailbox
433  * @hw: pointer to the HW structure
434  * @msg: The message buffer
435  * @size: Length of buffer
436  *
437  * returns 0 if it successfully read message from buffer
438  **/
ixgbevf_poll_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size)439 s32 ixgbevf_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
440 {
441 	struct ixgbe_mbx_info *mbx = &hw->mbx;
442 	s32 ret_val = IXGBE_ERR_CONFIG;
443 
444 	if (!mbx->ops.read || !mbx->ops.check_for_msg || !mbx->timeout)
445 		return ret_val;
446 
447 	/* limit read to size of mailbox */
448 	if (size > mbx->size)
449 		size = mbx->size;
450 
451 	ret_val = ixgbevf_poll_for_msg(hw);
452 	/* if ack received read message, otherwise we timed out */
453 	if (!ret_val)
454 		ret_val = mbx->ops.read(hw, msg, size);
455 
456 	return ret_val;
457 }
458 
459 /**
460  * ixgbevf_write_mbx - Write a message to the mailbox and wait for ACK
461  * @hw: pointer to the HW structure
462  * @msg: The message buffer
463  * @size: Length of buffer
464  *
465  * returns 0 if it successfully copied message into the buffer and
466  * received an ACK to that message within specified period
467  **/
ixgbevf_write_mbx(struct ixgbe_hw * hw,u32 * msg,u16 size)468 s32 ixgbevf_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)
469 {
470 	struct ixgbe_mbx_info *mbx = &hw->mbx;
471 	s32 ret_val = IXGBE_ERR_CONFIG;
472 
473 	/**
474 	 * exit if either we can't write, release
475 	 * or there is no timeout defined
476 	 */
477 	if (!mbx->ops.write || !mbx->ops.check_for_ack || !mbx->ops.release ||
478 	    !mbx->timeout)
479 		return ret_val;
480 
481 	if (size > mbx->size)
482 		ret_val = IXGBE_ERR_PARAM;
483 	else
484 		ret_val = mbx->ops.write(hw, msg, size);
485 
486 	return ret_val;
487 }
488 
489 const struct ixgbe_mbx_operations ixgbevf_mbx_ops = {
490 	.init_params	= ixgbevf_init_mbx_params_vf,
491 	.release	= ixgbevf_release_mbx_lock_vf,
492 	.read		= ixgbevf_read_mbx_vf,
493 	.write		= ixgbevf_write_mbx_vf,
494 	.check_for_msg	= ixgbevf_check_for_msg_vf,
495 	.check_for_ack	= ixgbevf_check_for_ack_vf,
496 	.check_for_rst	= ixgbevf_check_for_rst_vf,
497 };
498 
499 const struct ixgbe_mbx_operations ixgbevf_mbx_ops_legacy = {
500 	.init_params	= ixgbevf_init_mbx_params_vf,
501 	.release	= ixgbevf_release_mbx_lock_vf_legacy,
502 	.read		= ixgbevf_read_mbx_vf_legacy,
503 	.write		= ixgbevf_write_mbx_vf_legacy,
504 	.check_for_msg	= ixgbevf_check_for_msg_vf,
505 	.check_for_ack	= ixgbevf_check_for_ack_vf,
506 	.check_for_rst	= ixgbevf_check_for_rst_vf,
507 };
508 
509 /* Mailbox operations when running on Hyper-V.
510  * On Hyper-V, PF/VF communication is not through the
511  * hardware mailbox; this communication is through
512  * a software mediated path.
513  * Most mail box operations are noop while running on
514  * Hyper-V.
515  */
516 const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops = {
517 	.init_params	= ixgbevf_init_mbx_params_vf,
518 	.check_for_rst	= ixgbevf_check_for_rst_vf,
519 };
520