1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2020
5 #include "txgbe_type.h"
10 * txgbe_read_mbx - Reads a message from the mailbox
11 * @hw: pointer to the HW structure
12 * @msg: The message buffer
13 * @size: Length of buffer
14 * @mbx_id: id of mailbox to read
16 * returns 0 if it successfully read message from buffer
18 s32 txgbe_read_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
20 struct txgbe_mbx_info *mbx = &hw->mbx;
21 s32 ret_val = TXGBE_ERR_MBX;
23 DEBUGFUNC("txgbe_read_mbx");
25 /* limit read to size of mailbox */
30 ret_val = mbx->read(hw, msg, size, mbx_id);
36 * txgbe_write_mbx - Write a message to the mailbox
37 * @hw: pointer to the HW structure
38 * @msg: The message buffer
39 * @size: Length of buffer
40 * @mbx_id: id of mailbox to write
42 * returns 0 if it successfully copied message into the buffer
44 s32 txgbe_write_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
46 struct txgbe_mbx_info *mbx = &hw->mbx;
49 DEBUGFUNC("txgbe_write_mbx");
51 if (size > mbx->size) {
52 ret_val = TXGBE_ERR_MBX;
53 DEBUGOUT("Invalid mailbox message size %d", size);
54 } else if (mbx->write) {
55 ret_val = mbx->write(hw, msg, size, mbx_id);
62 * txgbe_check_for_msg - checks to see if someone sent us mail
63 * @hw: pointer to the HW structure
64 * @mbx_id: id of mailbox to check
66 * returns 0 if the Status bit was found or else ERR_MBX
68 s32 txgbe_check_for_msg(struct txgbe_hw *hw, u16 mbx_id)
70 struct txgbe_mbx_info *mbx = &hw->mbx;
71 s32 ret_val = TXGBE_ERR_MBX;
73 DEBUGFUNC("txgbe_check_for_msg");
75 if (mbx->check_for_msg)
76 ret_val = mbx->check_for_msg(hw, mbx_id);
82 * txgbe_check_for_ack - checks to see if someone sent us ACK
83 * @hw: pointer to the HW structure
84 * @mbx_id: id of mailbox to check
86 * returns 0 if the Status bit was found or else ERR_MBX
88 s32 txgbe_check_for_ack(struct txgbe_hw *hw, u16 mbx_id)
90 struct txgbe_mbx_info *mbx = &hw->mbx;
91 s32 ret_val = TXGBE_ERR_MBX;
93 DEBUGFUNC("txgbe_check_for_ack");
95 if (mbx->check_for_ack)
96 ret_val = mbx->check_for_ack(hw, mbx_id);
102 * txgbe_check_for_rst - checks to see if other side has reset
103 * @hw: pointer to the HW structure
104 * @mbx_id: id of mailbox to check
106 * returns 0 if the Status bit was found or else ERR_MBX
108 s32 txgbe_check_for_rst(struct txgbe_hw *hw, u16 mbx_id)
110 struct txgbe_mbx_info *mbx = &hw->mbx;
111 s32 ret_val = TXGBE_ERR_MBX;
113 DEBUGFUNC("txgbe_check_for_rst");
115 if (mbx->check_for_rst)
116 ret_val = mbx->check_for_rst(hw, mbx_id);
122 * txgbe_poll_for_msg - Wait for message notification
123 * @hw: pointer to the HW structure
124 * @mbx_id: id of mailbox to write
126 * returns SUCCESS if it successfully received a message notification
128 STATIC s32 txgbe_poll_for_msg(struct txgbe_hw *hw, u16 mbx_id)
130 struct txgbe_mbx_info *mbx = &hw->mbx;
131 int countdown = mbx->timeout;
133 DEBUGFUNC("txgbe_poll_for_msg");
135 if (!countdown || !mbx->check_for_msg)
138 while (countdown && mbx->check_for_msg(hw, mbx_id)) {
142 usec_delay(mbx->usec_delay);
146 DEBUGOUT("Polling for VF%d mailbox message timedout", mbx_id);
149 return countdown ? 0 : TXGBE_ERR_MBX;
153 * txgbe_poll_for_ack - Wait for message acknowledgment
154 * @hw: pointer to the HW structure
155 * @mbx_id: id of mailbox to write
157 * returns SUCCESS if it successfully received a message acknowledgment
159 STATIC s32 txgbe_poll_for_ack(struct txgbe_hw *hw, u16 mbx_id)
161 struct txgbe_mbx_info *mbx = &hw->mbx;
162 int countdown = mbx->timeout;
164 DEBUGFUNC("txgbe_poll_for_ack");
166 if (!countdown || !mbx->check_for_ack)
169 while (countdown && mbx->check_for_ack(hw, mbx_id)) {
173 usec_delay(mbx->usec_delay);
177 DEBUGOUT("Polling for VF%d mailbox ack timedout", mbx_id);
180 return countdown ? 0 : TXGBE_ERR_MBX;
184 * txgbe_read_posted_mbx - Wait for message notification and receive message
185 * @hw: pointer to the HW structure
186 * @msg: The message buffer
187 * @size: Length of buffer
188 * @mbx_id: id of mailbox to write
190 * returns SUCCESS if it successfully received a message notification and
191 * copied it into the receive buffer.
193 s32 txgbe_read_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
195 struct txgbe_mbx_info *mbx = &hw->mbx;
196 s32 ret_val = TXGBE_ERR_MBX;
198 DEBUGFUNC("txgbe_read_posted_mbx");
203 ret_val = txgbe_poll_for_msg(hw, mbx_id);
205 /* if ack received read message, otherwise we timed out */
207 ret_val = mbx->read(hw, msg, size, mbx_id);
213 * txgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
214 * @hw: pointer to the HW structure
215 * @msg: The message buffer
216 * @size: Length of buffer
217 * @mbx_id: id of mailbox to write
219 * returns SUCCESS if it successfully copied message into the buffer and
220 * received an ack to that message within delay * timeout period
222 s32 txgbe_write_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size,
225 struct txgbe_mbx_info *mbx = &hw->mbx;
226 s32 ret_val = TXGBE_ERR_MBX;
228 DEBUGFUNC("txgbe_write_posted_mbx");
230 /* exit if either we can't write or there isn't a defined timeout */
231 if (!mbx->write || !mbx->timeout)
235 ret_val = mbx->write(hw, msg, size, mbx_id);
237 /* if msg sent wait until we receive an ack */
239 ret_val = txgbe_poll_for_ack(hw, mbx_id);
245 * txgbe_read_v2p_mailbox - read v2p mailbox
246 * @hw: pointer to the HW structure
248 * This function is used to read the v2p mailbox without losing the read to
251 STATIC u32 txgbe_read_v2p_mailbox(struct txgbe_hw *hw)
253 u32 v2p_mailbox = rd32(hw, TXGBE_VFMBCTL);
255 v2p_mailbox |= hw->mbx.v2p_mailbox;
256 hw->mbx.v2p_mailbox |= v2p_mailbox & TXGBE_VFMBCTL_R2C_BITS;
262 * txgbe_check_for_bit_vf - Determine if a status bit was set
263 * @hw: pointer to the HW structure
264 * @mask: bitmask for bits to be tested and cleared
266 * This function is used to check for the read to clear bits within
269 STATIC s32 txgbe_check_for_bit_vf(struct txgbe_hw *hw, u32 mask)
271 u32 v2p_mailbox = txgbe_read_v2p_mailbox(hw);
272 s32 ret_val = TXGBE_ERR_MBX;
274 if (v2p_mailbox & mask)
277 hw->mbx.v2p_mailbox &= ~mask;
283 * txgbe_check_for_msg_vf - checks to see if the PF has sent mail
284 * @hw: pointer to the HW structure
285 * @mbx_id: id of mailbox to check
287 * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
289 s32 txgbe_check_for_msg_vf(struct txgbe_hw *hw, u16 mbx_id)
291 s32 ret_val = TXGBE_ERR_MBX;
293 UNREFERENCED_PARAMETER(mbx_id);
294 DEBUGFUNC("txgbe_check_for_msg_vf");
296 if (!txgbe_check_for_bit_vf(hw, TXGBE_VFMBCTL_PFSTS)) {
298 hw->mbx.stats.reqs++;
305 * txgbe_check_for_ack_vf - checks to see if the PF has ACK'd
306 * @hw: pointer to the HW structure
307 * @mbx_id: id of mailbox to check
309 * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
311 s32 txgbe_check_for_ack_vf(struct txgbe_hw *hw, u16 mbx_id)
313 s32 ret_val = TXGBE_ERR_MBX;
315 UNREFERENCED_PARAMETER(mbx_id);
316 DEBUGFUNC("txgbe_check_for_ack_vf");
318 if (!txgbe_check_for_bit_vf(hw, TXGBE_VFMBCTL_PFACK)) {
320 hw->mbx.stats.acks++;
327 * txgbe_check_for_rst_vf - checks to see if the PF has reset
328 * @hw: pointer to the HW structure
329 * @mbx_id: id of mailbox to check
331 * returns true if the PF has set the reset done bit or else false
333 s32 txgbe_check_for_rst_vf(struct txgbe_hw *hw, u16 mbx_id)
335 s32 ret_val = TXGBE_ERR_MBX;
337 UNREFERENCED_PARAMETER(mbx_id);
338 DEBUGFUNC("txgbe_check_for_rst_vf");
340 if (!txgbe_check_for_bit_vf(hw, (TXGBE_VFMBCTL_RSTD |
341 TXGBE_VFMBCTL_RSTI))) {
343 hw->mbx.stats.rsts++;
350 * txgbe_obtain_mbx_lock_vf - obtain mailbox lock
351 * @hw: pointer to the HW structure
353 * return SUCCESS if we obtained the mailbox lock
355 STATIC s32 txgbe_obtain_mbx_lock_vf(struct txgbe_hw *hw)
357 s32 ret_val = TXGBE_ERR_MBX;
359 DEBUGFUNC("txgbe_obtain_mbx_lock_vf");
361 /* Take ownership of the buffer */
362 wr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_VFU);
364 /* reserve mailbox for vf use */
365 if (txgbe_read_v2p_mailbox(hw) & TXGBE_VFMBCTL_VFU)
372 * txgbe_write_mbx_vf - Write a message to the mailbox
373 * @hw: pointer to the HW structure
374 * @msg: The message buffer
375 * @size: Length of buffer
376 * @mbx_id: id of mailbox to write
378 * returns SUCCESS if it successfully copied message into the buffer
380 s32 txgbe_write_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size,
386 UNREFERENCED_PARAMETER(mbx_id);
388 DEBUGFUNC("txgbe_write_mbx_vf");
390 /* lock the mailbox to prevent pf/vf race condition */
391 ret_val = txgbe_obtain_mbx_lock_vf(hw);
395 /* flush msg and acks as we are overwriting the message buffer */
396 txgbe_check_for_msg_vf(hw, 0);
397 txgbe_check_for_ack_vf(hw, 0);
399 /* copy the caller specified message to the mailbox memory buffer */
400 for (i = 0; i < size; i++)
401 wr32a(hw, TXGBE_VFMBX, i, msg[i]);
404 hw->mbx.stats.msgs_tx++;
406 /* Drop VFU and interrupt the PF to tell it a message has been sent */
407 wr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_REQ);
414 * txgbe_read_mbx_vf - Reads a message from the inbox intended for vf
415 * @hw: pointer to the HW structure
416 * @msg: The message buffer
417 * @size: Length of buffer
418 * @mbx_id: id of mailbox to read
420 * returns SUCCESS if it successfully read message from buffer
422 s32 txgbe_read_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size,
428 DEBUGFUNC("txgbe_read_mbx_vf");
429 UNREFERENCED_PARAMETER(mbx_id);
431 /* lock the mailbox to prevent pf/vf race condition */
432 ret_val = txgbe_obtain_mbx_lock_vf(hw);
436 /* copy the message from the mailbox memory buffer */
437 for (i = 0; i < size; i++)
438 msg[i] = rd32a(hw, TXGBE_VFMBX, i);
440 /* Acknowledge receipt and release mailbox, then we're done */
441 wr32(hw, TXGBE_VFMBCTL, TXGBE_VFMBCTL_ACK);
444 hw->mbx.stats.msgs_rx++;
451 * txgbe_init_mbx_params_vf - set initial values for vf mailbox
452 * @hw: pointer to the HW structure
454 * Initializes the hw->mbx struct to correct values for vf mailbox
456 void txgbe_init_mbx_params_vf(struct txgbe_hw *hw)
458 struct txgbe_mbx_info *mbx = &hw->mbx;
460 /* start mailbox as timed out and let the reset_hw call set the timeout
461 * value to begin communications
464 mbx->usec_delay = TXGBE_VF_MBX_INIT_DELAY;
466 mbx->size = TXGBE_P2VMBX_SIZE;
468 mbx->stats.msgs_tx = 0;
469 mbx->stats.msgs_rx = 0;
475 STATIC s32 txgbe_check_for_bit_pf(struct txgbe_hw *hw, u32 mask, s32 index)
477 u32 mbvficr = rd32(hw, TXGBE_MBVFICR(index));
478 s32 ret_val = TXGBE_ERR_MBX;
480 if (mbvficr & mask) {
482 wr32(hw, TXGBE_MBVFICR(index), mask);
489 * txgbe_check_for_msg_pf - checks to see if the VF has sent mail
490 * @hw: pointer to the HW structure
491 * @vf_number: the VF index
493 * returns 0 if the VF has set the Status bit or else ERR_MBX
495 s32 txgbe_check_for_msg_pf(struct txgbe_hw *hw, u16 vf_number)
497 s32 ret_val = TXGBE_ERR_MBX;
498 s32 index = TXGBE_MBVFICR_INDEX(vf_number);
499 u32 vf_bit = vf_number % 16;
501 DEBUGFUNC("txgbe_check_for_msg_pf");
503 if (!txgbe_check_for_bit_pf(hw, TXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
506 hw->mbx.stats.reqs++;
513 * txgbe_check_for_ack_pf - checks to see if the VF has ACKed
514 * @hw: pointer to the HW structure
515 * @vf_number: the VF index
517 * returns 0 if the VF has set the Status bit or else ERR_MBX
519 s32 txgbe_check_for_ack_pf(struct txgbe_hw *hw, u16 vf_number)
521 s32 ret_val = TXGBE_ERR_MBX;
522 s32 index = TXGBE_MBVFICR_INDEX(vf_number);
523 u32 vf_bit = vf_number % 16;
525 DEBUGFUNC("txgbe_check_for_ack_pf");
527 if (!txgbe_check_for_bit_pf(hw, TXGBE_MBVFICR_VFACK_VF1 << vf_bit,
530 hw->mbx.stats.acks++;
537 * txgbe_check_for_rst_pf - checks to see if the VF has reset
538 * @hw: pointer to the HW structure
539 * @vf_number: the VF index
541 * returns 0 if the VF has set the Status bit or else ERR_MBX
543 s32 txgbe_check_for_rst_pf(struct txgbe_hw *hw, u16 vf_number)
545 u32 reg_offset = (vf_number < 32) ? 0 : 1;
546 u32 vf_shift = vf_number % 32;
548 s32 ret_val = TXGBE_ERR_MBX;
550 DEBUGFUNC("txgbe_check_for_rst_pf");
552 vflre = rd32(hw, TXGBE_FLRVFE(reg_offset));
553 if (vflre & (1 << vf_shift)) {
555 wr32(hw, TXGBE_FLRVFEC(reg_offset), (1 << vf_shift));
556 hw->mbx.stats.rsts++;
563 * txgbe_obtain_mbx_lock_pf - obtain mailbox lock
564 * @hw: pointer to the HW structure
565 * @vf_number: the VF index
567 * return 0 if we obtained the mailbox lock
569 STATIC s32 txgbe_obtain_mbx_lock_pf(struct txgbe_hw *hw, u16 vf_number)
571 s32 ret_val = TXGBE_ERR_MBX;
574 DEBUGFUNC("txgbe_obtain_mbx_lock_pf");
576 /* Take ownership of the buffer */
577 wr32(hw, TXGBE_MBCTL(vf_number), TXGBE_MBCTL_PFU);
579 /* reserve mailbox for vf use */
580 p2v_mailbox = rd32(hw, TXGBE_MBCTL(vf_number));
581 if (p2v_mailbox & TXGBE_MBCTL_PFU)
584 DEBUGOUT("Failed to obtain mailbox lock for VF%d", vf_number);
591 * txgbe_write_mbx_pf - Places a message in the mailbox
592 * @hw: pointer to the HW structure
593 * @msg: The message buffer
594 * @size: Length of buffer
595 * @vf_number: the VF index
597 * returns 0 if it successfully copied message into the buffer
599 s32 txgbe_write_mbx_pf(struct txgbe_hw *hw, u32 *msg, u16 size, u16 vf_number)
604 DEBUGFUNC("txgbe_write_mbx_pf");
606 /* lock the mailbox to prevent pf/vf race condition */
607 ret_val = txgbe_obtain_mbx_lock_pf(hw, vf_number);
611 /* flush msg and acks as we are overwriting the message buffer */
612 txgbe_check_for_msg_pf(hw, vf_number);
613 txgbe_check_for_ack_pf(hw, vf_number);
615 /* copy the caller specified message to the mailbox memory buffer */
616 for (i = 0; i < size; i++)
617 wr32a(hw, TXGBE_MBMEM(vf_number), i, msg[i]);
619 /* Interrupt VF to tell it a message has been sent and release buffer*/
620 wr32(hw, TXGBE_MBCTL(vf_number), TXGBE_MBCTL_STS);
623 hw->mbx.stats.msgs_tx++;
630 * txgbe_read_mbx_pf - Read a message from the mailbox
631 * @hw: pointer to the HW structure
632 * @msg: The message buffer
633 * @size: Length of buffer
634 * @vf_number: the VF index
636 * This function copies a message from the mailbox buffer to the caller's
637 * memory buffer. The presumption is that the caller knows that there was
638 * a message due to a VF request so no polling for message is needed.
640 s32 txgbe_read_mbx_pf(struct txgbe_hw *hw, u32 *msg, u16 size, u16 vf_number)
645 DEBUGFUNC("txgbe_read_mbx_pf");
647 /* lock the mailbox to prevent pf/vf race condition */
648 ret_val = txgbe_obtain_mbx_lock_pf(hw, vf_number);
652 /* copy the message to the mailbox memory buffer */
653 for (i = 0; i < size; i++)
654 msg[i] = rd32a(hw, TXGBE_MBMEM(vf_number), i);
656 /* Acknowledge the message and release buffer */
657 wr32(hw, TXGBE_MBCTL(vf_number), TXGBE_MBCTL_ACK);
660 hw->mbx.stats.msgs_rx++;
667 * txgbe_init_mbx_params_pf - set initial values for pf mailbox
668 * @hw: pointer to the HW structure
670 * Initializes the hw->mbx struct to correct values for pf mailbox
672 void txgbe_init_mbx_params_pf(struct txgbe_hw *hw)
674 struct txgbe_mbx_info *mbx = &hw->mbx;
679 mbx->size = TXGBE_P2VMBX_SIZE;
681 mbx->stats.msgs_tx = 0;
682 mbx->stats.msgs_rx = 0;