1 /*******************************************************************************
3 Copyright (c) 2001-2012, Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
32 ***************************************************************************/
34 #include "ixgbe_type.h"
35 #include "ixgbe_mbx.h"
38 * ixgbe_read_mbx - Reads a message from the mailbox
39 * @hw: pointer to the HW structure
40 * @msg: The message buffer
41 * @size: Length of buffer
42 * @mbx_id: id of mailbox to read
44 * returns SUCCESS if it successfuly read message from buffer
46 s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
48 struct ixgbe_mbx_info *mbx = &hw->mbx;
49 s32 ret_val = IXGBE_ERR_MBX;
51 DEBUGFUNC("ixgbe_read_mbx");
53 /* limit read to size of mailbox */
58 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
64 * ixgbe_write_mbx - Write a message to the mailbox
65 * @hw: pointer to the HW structure
66 * @msg: The message buffer
67 * @size: Length of buffer
68 * @mbx_id: id of mailbox to write
70 * returns SUCCESS if it successfully copied message into the buffer
72 s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
74 struct ixgbe_mbx_info *mbx = &hw->mbx;
75 s32 ret_val = IXGBE_SUCCESS;
77 DEBUGFUNC("ixgbe_write_mbx");
80 ret_val = IXGBE_ERR_MBX;
82 else if (mbx->ops.write)
83 ret_val = mbx->ops.write(hw, msg, size, mbx_id);
89 * ixgbe_check_for_msg - checks to see if someone sent us mail
90 * @hw: pointer to the HW structure
91 * @mbx_id: id of mailbox to check
93 * returns SUCCESS if the Status bit was found or else ERR_MBX
95 s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
97 struct ixgbe_mbx_info *mbx = &hw->mbx;
98 s32 ret_val = IXGBE_ERR_MBX;
100 DEBUGFUNC("ixgbe_check_for_msg");
102 if (mbx->ops.check_for_msg)
103 ret_val = mbx->ops.check_for_msg(hw, mbx_id);
109 * ixgbe_check_for_ack - checks to see if someone sent us ACK
110 * @hw: pointer to the HW structure
111 * @mbx_id: id of mailbox to check
113 * returns SUCCESS if the Status bit was found or else ERR_MBX
115 s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
117 struct ixgbe_mbx_info *mbx = &hw->mbx;
118 s32 ret_val = IXGBE_ERR_MBX;
120 DEBUGFUNC("ixgbe_check_for_ack");
122 if (mbx->ops.check_for_ack)
123 ret_val = mbx->ops.check_for_ack(hw, mbx_id);
129 * ixgbe_check_for_rst - checks to see if other side has reset
130 * @hw: pointer to the HW structure
131 * @mbx_id: id of mailbox to check
133 * returns SUCCESS if the Status bit was found or else ERR_MBX
135 s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
137 struct ixgbe_mbx_info *mbx = &hw->mbx;
138 s32 ret_val = IXGBE_ERR_MBX;
140 DEBUGFUNC("ixgbe_check_for_rst");
142 if (mbx->ops.check_for_rst)
143 ret_val = mbx->ops.check_for_rst(hw, mbx_id);
149 * ixgbe_poll_for_msg - Wait for message notification
150 * @hw: pointer to the HW structure
151 * @mbx_id: id of mailbox to write
153 * returns SUCCESS if it successfully received a message notification
155 STATIC s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
157 struct ixgbe_mbx_info *mbx = &hw->mbx;
158 int countdown = mbx->timeout;
160 DEBUGFUNC("ixgbe_poll_for_msg");
162 if (!countdown || !mbx->ops.check_for_msg)
165 while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
169 usec_delay(mbx->usec_delay);
173 return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
177 * ixgbe_poll_for_ack - Wait for message acknowledgement
178 * @hw: pointer to the HW structure
179 * @mbx_id: id of mailbox to write
181 * returns SUCCESS if it successfully received a message acknowledgement
183 STATIC s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
185 struct ixgbe_mbx_info *mbx = &hw->mbx;
186 int countdown = mbx->timeout;
188 DEBUGFUNC("ixgbe_poll_for_ack");
190 if (!countdown || !mbx->ops.check_for_ack)
193 while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
197 usec_delay(mbx->usec_delay);
201 return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
205 * ixgbe_read_posted_mbx - Wait for message notification and receive message
206 * @hw: pointer to the HW structure
207 * @msg: The message buffer
208 * @size: Length of buffer
209 * @mbx_id: id of mailbox to write
211 * returns SUCCESS if it successfully received a message notification and
212 * copied it into the receive buffer.
214 s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
216 struct ixgbe_mbx_info *mbx = &hw->mbx;
217 s32 ret_val = IXGBE_ERR_MBX;
219 DEBUGFUNC("ixgbe_read_posted_mbx");
224 ret_val = ixgbe_poll_for_msg(hw, mbx_id);
226 /* if ack received read message, otherwise we timed out */
228 ret_val = mbx->ops.read(hw, msg, size, mbx_id);
234 * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
235 * @hw: pointer to the HW structure
236 * @msg: The message buffer
237 * @size: Length of buffer
238 * @mbx_id: id of mailbox to write
240 * returns SUCCESS if it successfully copied message into the buffer and
241 * received an ack to that message within delay * timeout period
243 s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
246 struct ixgbe_mbx_info *mbx = &hw->mbx;
247 s32 ret_val = IXGBE_ERR_MBX;
249 DEBUGFUNC("ixgbe_write_posted_mbx");
251 /* exit if either we can't write or there isn't a defined timeout */
252 if (!mbx->ops.write || !mbx->timeout)
256 ret_val = mbx->ops.write(hw, msg, size, mbx_id);
258 /* if msg sent wait until we receive an ack */
260 ret_val = ixgbe_poll_for_ack(hw, mbx_id);
266 * ixgbe_init_mbx_ops_generic - Initialize MB function pointers
267 * @hw: pointer to the HW structure
269 * Setups up the mailbox read and write message function pointers
271 void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
273 struct ixgbe_mbx_info *mbx = &hw->mbx;
275 mbx->ops.read_posted = ixgbe_read_posted_mbx;
276 mbx->ops.write_posted = ixgbe_write_posted_mbx;
280 * ixgbe_read_v2p_mailbox - read v2p mailbox
281 * @hw: pointer to the HW structure
283 * This function is used to read the v2p mailbox without losing the read to
286 STATIC u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
288 u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
290 v2p_mailbox |= hw->mbx.v2p_mailbox;
291 hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
297 * ixgbe_check_for_bit_vf - Determine if a status bit was set
298 * @hw: pointer to the HW structure
299 * @mask: bitmask for bits to be tested and cleared
301 * This function is used to check for the read to clear bits within
304 STATIC s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
306 u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
307 s32 ret_val = IXGBE_ERR_MBX;
309 if (v2p_mailbox & mask)
310 ret_val = IXGBE_SUCCESS;
312 hw->mbx.v2p_mailbox &= ~mask;
318 * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
319 * @hw: pointer to the HW structure
320 * @mbx_id: id of mailbox to check
322 * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
324 STATIC s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
326 s32 ret_val = IXGBE_ERR_MBX;
328 DEBUGFUNC("ixgbe_check_for_msg_vf");
330 if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
331 ret_val = IXGBE_SUCCESS;
332 hw->mbx.stats.reqs++;
339 * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
340 * @hw: pointer to the HW structure
341 * @mbx_id: id of mailbox to check
343 * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
345 STATIC s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
347 s32 ret_val = IXGBE_ERR_MBX;
349 DEBUGFUNC("ixgbe_check_for_ack_vf");
351 if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
352 ret_val = IXGBE_SUCCESS;
353 hw->mbx.stats.acks++;
360 * ixgbe_check_for_rst_vf - checks to see if the PF has reset
361 * @hw: pointer to the HW structure
362 * @mbx_id: id of mailbox to check
364 * returns true if the PF has set the reset done bit or else false
366 STATIC s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
368 s32 ret_val = IXGBE_ERR_MBX;
370 DEBUGFUNC("ixgbe_check_for_rst_vf");
372 if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
373 IXGBE_VFMAILBOX_RSTI))) {
374 ret_val = IXGBE_SUCCESS;
375 hw->mbx.stats.rsts++;
382 * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
383 * @hw: pointer to the HW structure
385 * return SUCCESS if we obtained the mailbox lock
387 STATIC s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
389 s32 ret_val = IXGBE_ERR_MBX;
391 DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
393 /* Take ownership of the buffer */
394 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
396 /* reserve mailbox for vf use */
397 if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
398 ret_val = IXGBE_SUCCESS;
404 * ixgbe_write_mbx_vf - Write a message to the mailbox
405 * @hw: pointer to the HW structure
406 * @msg: The message buffer
407 * @size: Length of buffer
408 * @mbx_id: id of mailbox to write
410 * returns SUCCESS if it successfully copied message into the buffer
412 STATIC s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
419 DEBUGFUNC("ixgbe_write_mbx_vf");
421 /* lock the mailbox to prevent pf/vf race condition */
422 ret_val = ixgbe_obtain_mbx_lock_vf(hw);
426 /* flush msg and acks as we are overwriting the message buffer */
427 ixgbe_check_for_msg_vf(hw, 0);
428 ixgbe_check_for_ack_vf(hw, 0);
430 /* copy the caller specified message to the mailbox memory buffer */
431 for (i = 0; i < size; i++)
432 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
435 hw->mbx.stats.msgs_tx++;
437 /* Drop VFU and interrupt the PF to tell it a message has been sent */
438 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
445 * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
446 * @hw: pointer to the HW structure
447 * @msg: The message buffer
448 * @size: Length of buffer
449 * @mbx_id: id of mailbox to read
451 * returns SUCCESS if it successfuly read message from buffer
453 STATIC s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
456 s32 ret_val = IXGBE_SUCCESS;
459 DEBUGFUNC("ixgbe_read_mbx_vf");
461 /* lock the mailbox to prevent pf/vf race condition */
462 ret_val = ixgbe_obtain_mbx_lock_vf(hw);
466 /* copy the message from the mailbox memory buffer */
467 for (i = 0; i < size; i++)
468 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
470 /* Acknowledge receipt and release mailbox, then we're done */
471 IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
474 hw->mbx.stats.msgs_rx++;
481 * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
482 * @hw: pointer to the HW structure
484 * Initializes the hw->mbx struct to correct values for vf mailbox
486 void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
488 struct ixgbe_mbx_info *mbx = &hw->mbx;
490 /* start mailbox as timed out and let the reset_hw call set the timeout
491 * value to begin communications */
493 mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
495 mbx->size = IXGBE_VFMAILBOX_SIZE;
497 mbx->ops.read = ixgbe_read_mbx_vf;
498 mbx->ops.write = ixgbe_write_mbx_vf;
499 mbx->ops.read_posted = ixgbe_read_posted_mbx;
500 mbx->ops.write_posted = ixgbe_write_posted_mbx;
501 mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
502 mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
503 mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
505 mbx->stats.msgs_tx = 0;
506 mbx->stats.msgs_rx = 0;
512 STATIC s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
514 u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
515 s32 ret_val = IXGBE_ERR_MBX;
517 if (mbvficr & mask) {
518 ret_val = IXGBE_SUCCESS;
519 IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
526 * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
527 * @hw: pointer to the HW structure
528 * @vf_number: the VF index
530 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
532 STATIC s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
534 s32 ret_val = IXGBE_ERR_MBX;
535 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
536 u32 vf_bit = vf_number % 16;
538 DEBUGFUNC("ixgbe_check_for_msg_pf");
540 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
542 ret_val = IXGBE_SUCCESS;
543 hw->mbx.stats.reqs++;
550 * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
551 * @hw: pointer to the HW structure
552 * @vf_number: the VF index
554 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
556 STATIC s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
558 s32 ret_val = IXGBE_ERR_MBX;
559 s32 index = IXGBE_MBVFICR_INDEX(vf_number);
560 u32 vf_bit = vf_number % 16;
562 DEBUGFUNC("ixgbe_check_for_ack_pf");
564 if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
566 ret_val = IXGBE_SUCCESS;
567 hw->mbx.stats.acks++;
574 * ixgbe_check_for_rst_pf - checks to see if the VF has reset
575 * @hw: pointer to the HW structure
576 * @vf_number: the VF index
578 * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
580 STATIC s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
582 u32 reg_offset = (vf_number < 32) ? 0 : 1;
583 u32 vf_shift = vf_number % 32;
585 s32 ret_val = IXGBE_ERR_MBX;
587 DEBUGFUNC("ixgbe_check_for_rst_pf");
589 switch (hw->mac.type) {
590 case ixgbe_mac_82599EB:
591 vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
594 vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
600 if (vflre & (1 << vf_shift)) {
601 ret_val = IXGBE_SUCCESS;
602 IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
603 hw->mbx.stats.rsts++;
610 * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
611 * @hw: pointer to the HW structure
612 * @vf_number: the VF index
614 * return SUCCESS if we obtained the mailbox lock
616 STATIC s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
618 s32 ret_val = IXGBE_ERR_MBX;
621 DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
623 /* Take ownership of the buffer */
624 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
626 /* reserve mailbox for vf use */
627 p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
628 if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
629 ret_val = IXGBE_SUCCESS;
635 * ixgbe_write_mbx_pf - Places a message in the mailbox
636 * @hw: pointer to the HW structure
637 * @msg: The message buffer
638 * @size: Length of buffer
639 * @vf_number: the VF index
641 * returns SUCCESS if it successfully copied message into the buffer
643 STATIC s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
649 DEBUGFUNC("ixgbe_write_mbx_pf");
651 /* lock the mailbox to prevent pf/vf race condition */
652 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
656 /* flush msg and acks as we are overwriting the message buffer */
657 ixgbe_check_for_msg_pf(hw, vf_number);
658 ixgbe_check_for_ack_pf(hw, vf_number);
660 /* copy the caller specified message to the mailbox memory buffer */
661 for (i = 0; i < size; i++)
662 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
664 /* Interrupt VF to tell it a message has been sent and release buffer*/
665 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
668 hw->mbx.stats.msgs_tx++;
676 * ixgbe_read_mbx_pf - Read a message from the mailbox
677 * @hw: pointer to the HW structure
678 * @msg: The message buffer
679 * @size: Length of buffer
680 * @vf_number: the VF index
682 * This function copies a message from the mailbox buffer to the caller's
683 * memory buffer. The presumption is that the caller knows that there was
684 * a message due to a VF request so no polling for message is needed.
686 STATIC s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
692 DEBUGFUNC("ixgbe_read_mbx_pf");
694 /* lock the mailbox to prevent pf/vf race condition */
695 ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
699 /* copy the message to the mailbox memory buffer */
700 for (i = 0; i < size; i++)
701 msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
703 /* Acknowledge the message and release buffer */
704 IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
707 hw->mbx.stats.msgs_rx++;
714 * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
715 * @hw: pointer to the HW structure
717 * Initializes the hw->mbx struct to correct values for pf mailbox
719 void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
721 struct ixgbe_mbx_info *mbx = &hw->mbx;
723 if (hw->mac.type != ixgbe_mac_82599EB &&
724 hw->mac.type != ixgbe_mac_X540)
730 mbx->size = IXGBE_VFMAILBOX_SIZE;
732 mbx->ops.read = ixgbe_read_mbx_pf;
733 mbx->ops.write = ixgbe_write_mbx_pf;
734 mbx->ops.read_posted = ixgbe_read_posted_mbx;
735 mbx->ops.write_posted = ixgbe_write_posted_mbx;
736 mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
737 mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
738 mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
740 mbx->stats.msgs_tx = 0;
741 mbx->stats.msgs_rx = 0;