1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 1999 - 2018 Intel Corporation. */
8 * ixgbevf_poll_for_msg - Wait for message notification
9 * @hw: pointer to the HW structure
11 * returns 0 if it successfully received a message notification
13 static s32
ixgbevf_poll_for_msg(struct ixgbe_hw
*hw
)
15 struct ixgbe_mbx_info
*mbx
= &hw
->mbx
;
16 int countdown
= mbx
->timeout
;
18 if (!countdown
|| !mbx
->ops
.check_for_msg
)
19 return IXGBE_ERR_CONFIG
;
21 while (countdown
&& mbx
->ops
.check_for_msg(hw
)) {
26 return countdown
? 0 : IXGBE_ERR_TIMEOUT
;
30 * ixgbevf_poll_for_ack - Wait for message acknowledgment
31 * @hw: pointer to the HW structure
33 * returns 0 if it successfully received a message acknowledgment
35 static s32
ixgbevf_poll_for_ack(struct ixgbe_hw
*hw
)
37 struct ixgbe_mbx_info
*mbx
= &hw
->mbx
;
38 int countdown
= mbx
->timeout
;
40 if (!countdown
|| !mbx
->ops
.check_for_ack
)
41 return IXGBE_ERR_CONFIG
;
43 while (countdown
&& mbx
->ops
.check_for_ack(hw
)) {
48 return countdown
? 0 : IXGBE_ERR_TIMEOUT
;
52 * ixgbevf_read_mailbox_vf - read VF's mailbox register
53 * @hw: pointer to the HW structure
55 * This function is used to read the mailbox register dedicated for VF without
56 * losing the read to clear status bits.
58 static u32
ixgbevf_read_mailbox_vf(struct ixgbe_hw
*hw
)
60 u32 vf_mailbox
= IXGBE_READ_REG(hw
, IXGBE_VFMAILBOX
);
62 vf_mailbox
|= hw
->mbx
.vf_mailbox
;
63 hw
->mbx
.vf_mailbox
|= vf_mailbox
& IXGBE_VFMAILBOX_R2C_BITS
;
69 * ixgbevf_clear_msg_vf - clear PF status bit
70 * @hw: pointer to the HW structure
72 * This function is used to clear PFSTS bit in the VFMAILBOX register
74 static void ixgbevf_clear_msg_vf(struct ixgbe_hw
*hw
)
76 u32 vf_mailbox
= ixgbevf_read_mailbox_vf(hw
);
78 if (vf_mailbox
& IXGBE_VFMAILBOX_PFSTS
) {
80 hw
->mbx
.vf_mailbox
&= ~IXGBE_VFMAILBOX_PFSTS
;
85 * ixgbevf_clear_ack_vf - clear PF ACK bit
86 * @hw: pointer to the HW structure
88 * This function is used to clear PFACK bit in the VFMAILBOX register
90 static void ixgbevf_clear_ack_vf(struct ixgbe_hw
*hw
)
92 u32 vf_mailbox
= ixgbevf_read_mailbox_vf(hw
);
94 if (vf_mailbox
& IXGBE_VFMAILBOX_PFACK
) {
96 hw
->mbx
.vf_mailbox
&= ~IXGBE_VFMAILBOX_PFACK
;
101 * ixgbevf_clear_rst_vf - clear PF reset bit
102 * @hw: pointer to the HW structure
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.
107 static void ixgbevf_clear_rst_vf(struct ixgbe_hw
*hw
)
109 u32 vf_mailbox
= ixgbevf_read_mailbox_vf(hw
);
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
);
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
123 * This function is used to check for the read to clear bits within
126 static s32
ixgbevf_check_for_bit_vf(struct ixgbe_hw
*hw
, u32 mask
)
128 u32 vf_mailbox
= ixgbevf_read_mailbox_vf(hw
);
129 s32 ret_val
= IXGBE_ERR_MBX
;
131 if (vf_mailbox
& mask
)
138 * ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail
139 * @hw: pointer to the HW structure
141 * returns 0 if the PF has set the Status bit or else ERR_MBX
143 static s32
ixgbevf_check_for_msg_vf(struct ixgbe_hw
*hw
)
145 s32 ret_val
= IXGBE_ERR_MBX
;
147 if (!ixgbevf_check_for_bit_vf(hw
, IXGBE_VFMAILBOX_PFSTS
)) {
149 hw
->mbx
.stats
.reqs
++;
156 * ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd
157 * @hw: pointer to the HW structure
159 * returns 0 if the PF has set the ACK bit or else ERR_MBX
161 static s32
ixgbevf_check_for_ack_vf(struct ixgbe_hw
*hw
)
163 s32 ret_val
= IXGBE_ERR_MBX
;
165 if (!ixgbevf_check_for_bit_vf(hw
, IXGBE_VFMAILBOX_PFACK
)) {
167 ixgbevf_clear_ack_vf(hw
);
168 hw
->mbx
.stats
.acks
++;
175 * ixgbevf_check_for_rst_vf - checks to see if the PF has reset
176 * @hw: pointer to the HW structure
178 * returns true if the PF has set the reset done bit or else false
180 static s32
ixgbevf_check_for_rst_vf(struct ixgbe_hw
*hw
)
182 s32 ret_val
= IXGBE_ERR_MBX
;
184 if (!ixgbevf_check_for_bit_vf(hw
, (IXGBE_VFMAILBOX_RSTD
|
185 IXGBE_VFMAILBOX_RSTI
))) {
187 ixgbevf_clear_rst_vf(hw
);
188 hw
->mbx
.stats
.rsts
++;
195 * ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock
196 * @hw: pointer to the HW structure
198 * return 0 if we obtained the mailbox lock
200 static s32
ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw
*hw
)
202 struct ixgbe_mbx_info
*mbx
= &hw
->mbx
;
203 s32 ret_val
= IXGBE_ERR_CONFIG
;
204 int countdown
= mbx
->timeout
;
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
);
216 /* Verify that VF is the owner of the lock */
217 if (ixgbevf_read_mailbox_vf(hw
) & IXGBE_VFMAILBOX_VFU
) {
222 /* Wait a bit before trying again */
227 ret_val
= IXGBE_ERR_TIMEOUT
;
233 * ixgbevf_release_mbx_lock_vf - release mailbox lock
234 * @hw: pointer to the HW structure
236 static void ixgbevf_release_mbx_lock_vf(struct ixgbe_hw
*hw
)
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
);
247 * ixgbevf_release_mbx_lock_vf_legacy - release mailbox lock
248 * @hw: pointer to the HW structure
250 static void ixgbevf_release_mbx_lock_vf_legacy(struct ixgbe_hw
*__always_unused hw
)
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
260 * returns 0 if it successfully copied message into the buffer
262 static s32
ixgbevf_write_mbx_vf(struct ixgbe_hw
*hw
, u32
*msg
, u16 size
)
268 /* lock the mailbox to prevent PF/VF race condition */
269 ret_val
= ixgbevf_obtain_mbx_lock_vf(hw
);
273 /* flush msg and acks as we are overwriting the message buffer */
274 ixgbevf_clear_msg_vf(hw
);
275 ixgbevf_clear_ack_vf(hw
);
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
]);
282 hw
->mbx
.stats
.msgs_tx
++;
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
);
289 /* if msg sent wait until we receive an ack */
290 ret_val
= ixgbevf_poll_for_ack(hw
);
293 hw
->mbx
.ops
.release(hw
);
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
304 * returns 0 if it successfully copied message into the buffer
306 static s32
ixgbevf_write_mbx_vf_legacy(struct ixgbe_hw
*hw
, u32
*msg
, u16 size
)
311 /* lock the mailbox to prevent PF/VF race condition */
312 ret_val
= ixgbevf_obtain_mbx_lock_vf(hw
);
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
);
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
]);
327 hw
->mbx
.stats
.msgs_tx
++;
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
);
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
342 * returns 0 if it successfully read message from buffer
344 static s32
ixgbevf_read_mbx_vf(struct ixgbe_hw
*hw
, u32
*msg
, u16 size
)
350 /* check if there is a message from PF */
351 ret_val
= ixgbevf_check_for_msg_vf(hw
);
355 ixgbevf_clear_msg_vf(hw
);
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
);
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
);
367 hw
->mbx
.stats
.msgs_rx
++;
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
378 * returns 0 if it successfully read message from buffer
380 static s32
ixgbevf_read_mbx_vf_legacy(struct ixgbe_hw
*hw
, u32
*msg
, u16 size
)
385 /* lock the mailbox to prevent PF/VF race condition */
386 ret_val
= ixgbevf_obtain_mbx_lock_vf(hw
);
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
);
394 /* Acknowledge receipt and release mailbox, then we're done */
395 IXGBE_WRITE_REG(hw
, IXGBE_VFMAILBOX
, IXGBE_VFMAILBOX_ACK
);
398 hw
->mbx
.stats
.msgs_rx
++;
405 * ixgbevf_init_mbx_params_vf - set initial values for VF mailbox
406 * @hw: pointer to the HW structure
408 * Initializes the hw->mbx struct to correct values for VF mailbox
410 static s32
ixgbevf_init_mbx_params_vf(struct ixgbe_hw
*hw
)
412 struct ixgbe_mbx_info
*mbx
= &hw
->mbx
;
414 /* start mailbox as timed out and let the reset_hw call set the timeout
415 * value to begin communications
417 mbx
->timeout
= IXGBE_VF_MBX_INIT_TIMEOUT
;
418 mbx
->udelay
= IXGBE_VF_MBX_INIT_DELAY
;
420 mbx
->size
= IXGBE_VFMAILBOX_SIZE
;
422 mbx
->stats
.msgs_tx
= 0;
423 mbx
->stats
.msgs_rx
= 0;
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
437 * returns 0 if it successfully read message from buffer
439 s32
ixgbevf_poll_mbx(struct ixgbe_hw
*hw
, u32
*msg
, u16 size
)
441 struct ixgbe_mbx_info
*mbx
= &hw
->mbx
;
442 s32 ret_val
= IXGBE_ERR_CONFIG
;
444 if (!mbx
->ops
.read
|| !mbx
->ops
.check_for_msg
|| !mbx
->timeout
)
447 /* limit read to size of mailbox */
448 if (size
> mbx
->size
)
451 ret_val
= ixgbevf_poll_for_msg(hw
);
452 /* if ack received read message, otherwise we timed out */
454 ret_val
= mbx
->ops
.read(hw
, msg
, size
);
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
465 * returns 0 if it successfully copied message into the buffer and
466 * received an ACK to that message within specified period
468 s32
ixgbevf_write_mbx(struct ixgbe_hw
*hw
, u32
*msg
, u16 size
)
470 struct ixgbe_mbx_info
*mbx
= &hw
->mbx
;
471 s32 ret_val
= IXGBE_ERR_CONFIG
;
474 * exit if either we can't write, release
475 * or there is no timeout defined
477 if (!mbx
->ops
.write
|| !mbx
->ops
.check_for_ack
|| !mbx
->ops
.release
||
481 if (size
> mbx
->size
)
482 ret_val
= IXGBE_ERR_PARAM
;
484 ret_val
= mbx
->ops
.write(hw
, msg
, size
);
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
,
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
,
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
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
,