Home | History | Annotate | Line # | Download | only in ixgbe
ixgbe_mbx.c revision 1.11
      1  1.11  msaitoh /* $NetBSD: ixgbe_mbx.c,v 1.11 2019/06/27 05:55:40 msaitoh Exp $ */
      2   1.7  msaitoh 
      3   1.1   dyoung /******************************************************************************
      4   1.9  msaitoh   SPDX-License-Identifier: BSD-3-Clause
      5   1.1   dyoung 
      6   1.7  msaitoh   Copyright (c) 2001-2017, Intel Corporation
      7   1.1   dyoung   All rights reserved.
      8   1.7  msaitoh 
      9   1.7  msaitoh   Redistribution and use in source and binary forms, with or without
     10   1.1   dyoung   modification, are permitted provided that the following conditions are met:
     11   1.7  msaitoh 
     12   1.7  msaitoh    1. Redistributions of source code must retain the above copyright notice,
     13   1.1   dyoung       this list of conditions and the following disclaimer.
     14   1.7  msaitoh 
     15   1.7  msaitoh    2. Redistributions in binary form must reproduce the above copyright
     16   1.7  msaitoh       notice, this list of conditions and the following disclaimer in the
     17   1.1   dyoung       documentation and/or other materials provided with the distribution.
     18   1.7  msaitoh 
     19   1.7  msaitoh    3. Neither the name of the Intel Corporation nor the names of its
     20   1.7  msaitoh       contributors may be used to endorse or promote products derived from
     21   1.1   dyoung       this software without specific prior written permission.
     22   1.7  msaitoh 
     23   1.1   dyoung   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     24   1.7  msaitoh   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25   1.7  msaitoh   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26   1.7  msaitoh   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     27   1.7  msaitoh   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     28   1.7  msaitoh   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     29   1.7  msaitoh   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30   1.7  msaitoh   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     31   1.7  msaitoh   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     32   1.1   dyoung   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     33   1.1   dyoung   POSSIBILITY OF SUCH DAMAGE.
     34   1.1   dyoung 
     35   1.1   dyoung ******************************************************************************/
     36  1.10  msaitoh /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_mbx.c 326022 2017-11-20 19:36:21Z pfg $*/
     37   1.1   dyoung 
     38   1.1   dyoung #include "ixgbe_type.h"
     39   1.1   dyoung #include "ixgbe_mbx.h"
     40   1.1   dyoung 
     41   1.1   dyoung /**
     42  1.11  msaitoh  *  ixgbe_clear_mbx - Clear Mailbox Memory
     43  1.11  msaitoh  *  @hw: pointer to the HW structure
     44  1.11  msaitoh  *  @vf_number: id of mailbox to write
     45  1.11  msaitoh  *
     46  1.11  msaitoh  *  Set VFMBMEM of given VF to 0x0.
     47  1.11  msaitoh  **/
     48  1.11  msaitoh s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 vf_number)
     49  1.11  msaitoh {
     50  1.11  msaitoh 	struct ixgbe_mbx_info *mbx = &hw->mbx;
     51  1.11  msaitoh 	s32 ret_val = IXGBE_SUCCESS;
     52  1.11  msaitoh 
     53  1.11  msaitoh 	DEBUGFUNC("ixgbe_clear_mbx");
     54  1.11  msaitoh 
     55  1.11  msaitoh 	if (mbx->ops.clear)
     56  1.11  msaitoh 		ret_val = mbx->ops.clear(hw, vf_number);
     57  1.11  msaitoh 
     58  1.11  msaitoh 	return ret_val;
     59  1.11  msaitoh }
     60  1.11  msaitoh 
     61  1.11  msaitoh /**
     62   1.1   dyoung  *  ixgbe_poll_for_msg - Wait for message notification
     63   1.1   dyoung  *  @hw: pointer to the HW structure
     64   1.1   dyoung  *  @mbx_id: id of mailbox to write
     65   1.1   dyoung  *
     66   1.1   dyoung  *  returns SUCCESS if it successfully received a message notification
     67   1.1   dyoung  **/
     68   1.1   dyoung static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
     69   1.1   dyoung {
     70   1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
     71   1.1   dyoung 	int countdown = mbx->timeout;
     72   1.1   dyoung 
     73   1.1   dyoung 	DEBUGFUNC("ixgbe_poll_for_msg");
     74   1.1   dyoung 
     75   1.1   dyoung 	if (!countdown || !mbx->ops.check_for_msg)
     76   1.1   dyoung 		goto out;
     77   1.1   dyoung 
     78   1.1   dyoung 	while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
     79   1.1   dyoung 		countdown--;
     80   1.1   dyoung 		if (!countdown)
     81   1.1   dyoung 			break;
     82   1.1   dyoung 		usec_delay(mbx->usec_delay);
     83   1.1   dyoung 	}
     84   1.1   dyoung 
     85   1.4  msaitoh 	if (countdown == 0)
     86   1.4  msaitoh 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
     87   1.4  msaitoh 			   "Polling for VF%d mailbox message timedout", mbx_id);
     88   1.4  msaitoh 
     89   1.1   dyoung out:
     90   1.1   dyoung 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
     91   1.1   dyoung }
     92   1.1   dyoung 
     93   1.1   dyoung /**
     94   1.1   dyoung  *  ixgbe_poll_for_ack - Wait for message acknowledgement
     95   1.1   dyoung  *  @hw: pointer to the HW structure
     96   1.1   dyoung  *  @mbx_id: id of mailbox to write
     97   1.1   dyoung  *
     98   1.1   dyoung  *  returns SUCCESS if it successfully received a message acknowledgement
     99   1.1   dyoung  **/
    100   1.1   dyoung static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
    101   1.1   dyoung {
    102   1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    103   1.1   dyoung 	int countdown = mbx->timeout;
    104   1.1   dyoung 
    105   1.1   dyoung 	DEBUGFUNC("ixgbe_poll_for_ack");
    106   1.1   dyoung 
    107   1.1   dyoung 	if (!countdown || !mbx->ops.check_for_ack)
    108   1.1   dyoung 		goto out;
    109   1.1   dyoung 
    110   1.1   dyoung 	while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
    111   1.1   dyoung 		countdown--;
    112   1.1   dyoung 		if (!countdown)
    113   1.1   dyoung 			break;
    114   1.1   dyoung 		usec_delay(mbx->usec_delay);
    115   1.1   dyoung 	}
    116   1.1   dyoung 
    117   1.4  msaitoh 	if (countdown == 0)
    118   1.4  msaitoh 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
    119   1.4  msaitoh 			     "Polling for VF%d mailbox ack timedout", mbx_id);
    120   1.4  msaitoh 
    121   1.1   dyoung out:
    122   1.1   dyoung 	return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
    123   1.1   dyoung }
    124   1.1   dyoung 
    125   1.1   dyoung /**
    126   1.1   dyoung  *  ixgbe_read_posted_mbx - Wait for message notification and receive message
    127   1.1   dyoung  *  @hw: pointer to the HW structure
    128   1.1   dyoung  *  @msg: The message buffer
    129   1.1   dyoung  *  @size: Length of buffer
    130   1.1   dyoung  *  @mbx_id: id of mailbox to write
    131   1.1   dyoung  *
    132   1.1   dyoung  *  returns SUCCESS if it successfully received a message notification and
    133   1.1   dyoung  *  copied it into the receive buffer.
    134   1.1   dyoung  **/
    135   1.7  msaitoh static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
    136   1.7  msaitoh 				 u16 mbx_id)
    137   1.1   dyoung {
    138   1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    139   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    140   1.1   dyoung 
    141   1.1   dyoung 	DEBUGFUNC("ixgbe_read_posted_mbx");
    142   1.1   dyoung 
    143   1.1   dyoung 	if (!mbx->ops.read)
    144   1.1   dyoung 		goto out;
    145   1.1   dyoung 
    146   1.1   dyoung 	ret_val = ixgbe_poll_for_msg(hw, mbx_id);
    147   1.1   dyoung 
    148   1.1   dyoung 	/* if ack received read message, otherwise we timed out */
    149   1.1   dyoung 	if (!ret_val)
    150   1.1   dyoung 		ret_val = mbx->ops.read(hw, msg, size, mbx_id);
    151   1.1   dyoung out:
    152   1.1   dyoung 	return ret_val;
    153   1.1   dyoung }
    154   1.1   dyoung 
    155   1.1   dyoung /**
    156   1.1   dyoung  *  ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
    157   1.1   dyoung  *  @hw: pointer to the HW structure
    158   1.1   dyoung  *  @msg: The message buffer
    159   1.1   dyoung  *  @size: Length of buffer
    160   1.1   dyoung  *  @mbx_id: id of mailbox to write
    161   1.1   dyoung  *
    162   1.1   dyoung  *  returns SUCCESS if it successfully copied message into the buffer and
    163   1.1   dyoung  *  received an ack to that message within delay * timeout period
    164   1.1   dyoung  **/
    165   1.7  msaitoh static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
    166   1.7  msaitoh 				  u16 mbx_id)
    167   1.1   dyoung {
    168   1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    169   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    170   1.1   dyoung 
    171   1.1   dyoung 	DEBUGFUNC("ixgbe_write_posted_mbx");
    172   1.1   dyoung 
    173   1.1   dyoung 	/* exit if either we can't write or there isn't a defined timeout */
    174   1.1   dyoung 	if (!mbx->ops.write || !mbx->timeout)
    175   1.1   dyoung 		goto out;
    176   1.1   dyoung 
    177   1.1   dyoung 	/* send msg */
    178   1.1   dyoung 	ret_val = mbx->ops.write(hw, msg, size, mbx_id);
    179   1.1   dyoung 
    180   1.1   dyoung 	/* if msg sent wait until we receive an ack */
    181   1.1   dyoung 	if (!ret_val)
    182   1.1   dyoung 		ret_val = ixgbe_poll_for_ack(hw, mbx_id);
    183   1.1   dyoung out:
    184   1.1   dyoung 	return ret_val;
    185   1.1   dyoung }
    186   1.1   dyoung 
    187   1.1   dyoung /**
    188   1.1   dyoung  *  ixgbe_init_mbx_ops_generic - Initialize MB function pointers
    189   1.1   dyoung  *  @hw: pointer to the HW structure
    190   1.1   dyoung  *
    191   1.1   dyoung  *  Setups up the mailbox read and write message function pointers
    192   1.1   dyoung  **/
    193   1.1   dyoung void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
    194   1.1   dyoung {
    195   1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    196   1.1   dyoung 
    197   1.1   dyoung 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
    198   1.1   dyoung 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
    199   1.1   dyoung }
    200   1.1   dyoung 
    201   1.1   dyoung /**
    202   1.1   dyoung  *  ixgbe_read_v2p_mailbox - read v2p mailbox
    203   1.1   dyoung  *  @hw: pointer to the HW structure
    204   1.1   dyoung  *
    205   1.1   dyoung  *  This function is used to read the v2p mailbox without losing the read to
    206   1.1   dyoung  *  clear status bits.
    207   1.1   dyoung  **/
    208   1.1   dyoung static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
    209   1.1   dyoung {
    210   1.1   dyoung 	u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
    211   1.1   dyoung 
    212   1.1   dyoung 	v2p_mailbox |= hw->mbx.v2p_mailbox;
    213   1.1   dyoung 	hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
    214   1.1   dyoung 
    215   1.1   dyoung 	return v2p_mailbox;
    216   1.1   dyoung }
    217   1.1   dyoung 
    218   1.1   dyoung /**
    219   1.1   dyoung  *  ixgbe_check_for_bit_vf - Determine if a status bit was set
    220   1.1   dyoung  *  @hw: pointer to the HW structure
    221   1.1   dyoung  *  @mask: bitmask for bits to be tested and cleared
    222   1.1   dyoung  *
    223   1.1   dyoung  *  This function is used to check for the read to clear bits within
    224   1.1   dyoung  *  the V2P mailbox.
    225   1.1   dyoung  **/
    226   1.1   dyoung static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
    227   1.1   dyoung {
    228   1.1   dyoung 	u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
    229   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    230   1.1   dyoung 
    231   1.1   dyoung 	if (v2p_mailbox & mask)
    232   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    233   1.1   dyoung 
    234   1.1   dyoung 	hw->mbx.v2p_mailbox &= ~mask;
    235   1.1   dyoung 
    236   1.1   dyoung 	return ret_val;
    237   1.1   dyoung }
    238   1.1   dyoung 
    239   1.1   dyoung /**
    240   1.1   dyoung  *  ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
    241   1.1   dyoung  *  @hw: pointer to the HW structure
    242   1.1   dyoung  *  @mbx_id: id of mailbox to check
    243   1.1   dyoung  *
    244   1.1   dyoung  *  returns SUCCESS if the PF has set the Status bit or else ERR_MBX
    245   1.1   dyoung  **/
    246   1.1   dyoung static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
    247   1.1   dyoung {
    248   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    249   1.1   dyoung 
    250   1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    251   1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_msg_vf");
    252   1.1   dyoung 
    253   1.1   dyoung 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
    254   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    255   1.8  msaitoh 		hw->mbx.stats.reqs.ev_count++;
    256   1.1   dyoung 	}
    257   1.1   dyoung 
    258   1.1   dyoung 	return ret_val;
    259   1.1   dyoung }
    260   1.1   dyoung 
    261   1.1   dyoung /**
    262   1.1   dyoung  *  ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
    263   1.1   dyoung  *  @hw: pointer to the HW structure
    264   1.1   dyoung  *  @mbx_id: id of mailbox to check
    265   1.1   dyoung  *
    266   1.1   dyoung  *  returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
    267   1.1   dyoung  **/
    268   1.1   dyoung static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
    269   1.1   dyoung {
    270   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    271   1.1   dyoung 
    272   1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    273   1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_ack_vf");
    274   1.1   dyoung 
    275   1.1   dyoung 	if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
    276   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    277   1.8  msaitoh 		hw->mbx.stats.acks.ev_count++;
    278   1.1   dyoung 	}
    279   1.1   dyoung 
    280   1.1   dyoung 	return ret_val;
    281   1.1   dyoung }
    282   1.1   dyoung 
    283   1.1   dyoung /**
    284   1.1   dyoung  *  ixgbe_check_for_rst_vf - checks to see if the PF has reset
    285   1.1   dyoung  *  @hw: pointer to the HW structure
    286   1.1   dyoung  *  @mbx_id: id of mailbox to check
    287   1.1   dyoung  *
    288   1.1   dyoung  *  returns TRUE if the PF has set the reset done bit or else FALSE
    289   1.1   dyoung  **/
    290   1.1   dyoung static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
    291   1.1   dyoung {
    292   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    293   1.1   dyoung 
    294   1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    295   1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_rst_vf");
    296   1.1   dyoung 
    297   1.1   dyoung 	if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
    298   1.2  msaitoh 	    IXGBE_VFMAILBOX_RSTI))) {
    299   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    300   1.8  msaitoh 		hw->mbx.stats.rsts.ev_count++;
    301   1.1   dyoung 	}
    302   1.1   dyoung 
    303   1.1   dyoung 	return ret_val;
    304   1.1   dyoung }
    305   1.1   dyoung 
    306   1.1   dyoung /**
    307   1.1   dyoung  *  ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
    308   1.1   dyoung  *  @hw: pointer to the HW structure
    309   1.1   dyoung  *
    310   1.1   dyoung  *  return SUCCESS if we obtained the mailbox lock
    311   1.1   dyoung  **/
    312   1.1   dyoung static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
    313   1.1   dyoung {
    314   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    315   1.1   dyoung 
    316   1.1   dyoung 	DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
    317   1.1   dyoung 
    318   1.1   dyoung 	/* Take ownership of the buffer */
    319   1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
    320   1.1   dyoung 
    321   1.1   dyoung 	/* reserve mailbox for vf use */
    322   1.1   dyoung 	if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
    323   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    324   1.1   dyoung 
    325   1.1   dyoung 	return ret_val;
    326   1.1   dyoung }
    327   1.1   dyoung 
    328   1.1   dyoung /**
    329   1.1   dyoung  *  ixgbe_write_mbx_vf - Write a message to the mailbox
    330   1.1   dyoung  *  @hw: pointer to the HW structure
    331   1.1   dyoung  *  @msg: The message buffer
    332   1.1   dyoung  *  @size: Length of buffer
    333   1.1   dyoung  *  @mbx_id: id of mailbox to write
    334   1.1   dyoung  *
    335   1.1   dyoung  *  returns SUCCESS if it successfully copied message into the buffer
    336   1.1   dyoung  **/
    337   1.1   dyoung static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    338   1.2  msaitoh 			      u16 mbx_id)
    339   1.1   dyoung {
    340   1.1   dyoung 	s32 ret_val;
    341   1.1   dyoung 	u16 i;
    342   1.1   dyoung 
    343   1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    344   1.1   dyoung 
    345   1.1   dyoung 	DEBUGFUNC("ixgbe_write_mbx_vf");
    346   1.1   dyoung 
    347   1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    348   1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    349   1.1   dyoung 	if (ret_val)
    350   1.1   dyoung 		goto out_no_write;
    351   1.1   dyoung 
    352   1.1   dyoung 	/* flush msg and acks as we are overwriting the message buffer */
    353   1.1   dyoung 	ixgbe_check_for_msg_vf(hw, 0);
    354   1.1   dyoung 	ixgbe_check_for_ack_vf(hw, 0);
    355   1.1   dyoung 
    356   1.1   dyoung 	/* copy the caller specified message to the mailbox memory buffer */
    357   1.1   dyoung 	for (i = 0; i < size; i++)
    358   1.1   dyoung 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
    359   1.1   dyoung 
    360   1.1   dyoung 	/* update stats */
    361   1.8  msaitoh 	hw->mbx.stats.msgs_tx.ev_count++;
    362   1.1   dyoung 
    363   1.1   dyoung 	/* Drop VFU and interrupt the PF to tell it a message has been sent */
    364   1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
    365   1.1   dyoung 
    366   1.1   dyoung out_no_write:
    367   1.1   dyoung 	return ret_val;
    368   1.1   dyoung }
    369   1.1   dyoung 
    370   1.1   dyoung /**
    371   1.1   dyoung  *  ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
    372   1.1   dyoung  *  @hw: pointer to the HW structure
    373   1.1   dyoung  *  @msg: The message buffer
    374   1.1   dyoung  *  @size: Length of buffer
    375   1.1   dyoung  *  @mbx_id: id of mailbox to read
    376   1.1   dyoung  *
    377   1.6  msaitoh  *  returns SUCCESS if it successfully read message from buffer
    378   1.1   dyoung  **/
    379   1.1   dyoung static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    380   1.2  msaitoh 			     u16 mbx_id)
    381   1.1   dyoung {
    382   1.1   dyoung 	s32 ret_val = IXGBE_SUCCESS;
    383   1.1   dyoung 	u16 i;
    384   1.1   dyoung 
    385   1.1   dyoung 	DEBUGFUNC("ixgbe_read_mbx_vf");
    386   1.2  msaitoh 	UNREFERENCED_1PARAMETER(mbx_id);
    387   1.1   dyoung 
    388   1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    389   1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_vf(hw);
    390   1.1   dyoung 	if (ret_val)
    391   1.1   dyoung 		goto out_no_read;
    392   1.1   dyoung 
    393   1.1   dyoung 	/* copy the message from the mailbox memory buffer */
    394   1.1   dyoung 	for (i = 0; i < size; i++)
    395   1.1   dyoung 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
    396   1.1   dyoung 
    397   1.1   dyoung 	/* Acknowledge receipt and release mailbox, then we're done */
    398   1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
    399   1.1   dyoung 
    400   1.1   dyoung 	/* update stats */
    401   1.8  msaitoh 	hw->mbx.stats.msgs_rx.ev_count++;
    402   1.1   dyoung 
    403   1.1   dyoung out_no_read:
    404   1.1   dyoung 	return ret_val;
    405   1.1   dyoung }
    406   1.1   dyoung 
    407   1.1   dyoung /**
    408   1.1   dyoung  *  ixgbe_init_mbx_params_vf - set initial values for vf mailbox
    409   1.1   dyoung  *  @hw: pointer to the HW structure
    410   1.1   dyoung  *
    411   1.1   dyoung  *  Initializes the hw->mbx struct to correct values for vf mailbox
    412   1.1   dyoung  */
    413   1.1   dyoung void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
    414   1.1   dyoung {
    415   1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    416   1.1   dyoung 
    417   1.1   dyoung 	/* start mailbox as timed out and let the reset_hw call set the timeout
    418   1.1   dyoung 	 * value to begin communications */
    419   1.1   dyoung 	mbx->timeout = 0;
    420   1.1   dyoung 	mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
    421   1.1   dyoung 
    422   1.1   dyoung 	mbx->size = IXGBE_VFMAILBOX_SIZE;
    423   1.1   dyoung 
    424   1.1   dyoung 	mbx->ops.read = ixgbe_read_mbx_vf;
    425   1.1   dyoung 	mbx->ops.write = ixgbe_write_mbx_vf;
    426   1.1   dyoung 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
    427   1.1   dyoung 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
    428   1.1   dyoung 	mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
    429   1.1   dyoung 	mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
    430   1.1   dyoung 	mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
    431  1.11  msaitoh 	mbx->ops.clear = NULL;
    432   1.1   dyoung 
    433   1.8  msaitoh 	mbx->stats.msgs_tx.ev_count = 0;
    434   1.8  msaitoh 	mbx->stats.msgs_rx.ev_count = 0;
    435   1.8  msaitoh 	mbx->stats.reqs.ev_count = 0;
    436   1.8  msaitoh 	mbx->stats.acks.ev_count = 0;
    437   1.8  msaitoh 	mbx->stats.rsts.ev_count = 0;
    438   1.1   dyoung }
    439   1.1   dyoung 
    440   1.1   dyoung static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
    441   1.1   dyoung {
    442   1.1   dyoung 	u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
    443   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    444   1.1   dyoung 
    445   1.1   dyoung 	if (mbvficr & mask) {
    446   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    447   1.1   dyoung 		IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
    448   1.1   dyoung 	}
    449   1.1   dyoung 
    450   1.1   dyoung 	return ret_val;
    451   1.1   dyoung }
    452   1.1   dyoung 
    453   1.1   dyoung /**
    454   1.1   dyoung  *  ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
    455   1.1   dyoung  *  @hw: pointer to the HW structure
    456   1.1   dyoung  *  @vf_number: the VF index
    457   1.1   dyoung  *
    458   1.1   dyoung  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    459   1.1   dyoung  **/
    460   1.1   dyoung static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
    461   1.1   dyoung {
    462   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    463   1.1   dyoung 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
    464   1.1   dyoung 	u32 vf_bit = vf_number % 16;
    465   1.1   dyoung 
    466   1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_msg_pf");
    467   1.1   dyoung 
    468   1.1   dyoung 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
    469   1.2  msaitoh 				    index)) {
    470   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    471   1.8  msaitoh 		hw->mbx.stats.reqs.ev_count++;
    472   1.1   dyoung 	}
    473   1.1   dyoung 
    474   1.1   dyoung 	return ret_val;
    475   1.1   dyoung }
    476   1.1   dyoung 
    477   1.1   dyoung /**
    478   1.1   dyoung  *  ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
    479   1.1   dyoung  *  @hw: pointer to the HW structure
    480   1.1   dyoung  *  @vf_number: the VF index
    481   1.1   dyoung  *
    482   1.1   dyoung  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    483   1.1   dyoung  **/
    484   1.1   dyoung static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
    485   1.1   dyoung {
    486   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    487   1.1   dyoung 	s32 index = IXGBE_MBVFICR_INDEX(vf_number);
    488   1.1   dyoung 	u32 vf_bit = vf_number % 16;
    489   1.1   dyoung 
    490   1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_ack_pf");
    491   1.1   dyoung 
    492   1.1   dyoung 	if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
    493   1.2  msaitoh 				    index)) {
    494   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    495   1.8  msaitoh 		hw->mbx.stats.acks.ev_count++;
    496   1.1   dyoung 	}
    497   1.1   dyoung 
    498   1.1   dyoung 	return ret_val;
    499   1.1   dyoung }
    500   1.1   dyoung 
    501   1.1   dyoung /**
    502   1.1   dyoung  *  ixgbe_check_for_rst_pf - checks to see if the VF has reset
    503   1.1   dyoung  *  @hw: pointer to the HW structure
    504   1.1   dyoung  *  @vf_number: the VF index
    505   1.1   dyoung  *
    506   1.1   dyoung  *  returns SUCCESS if the VF has set the Status bit or else ERR_MBX
    507   1.1   dyoung  **/
    508   1.1   dyoung static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
    509   1.1   dyoung {
    510   1.1   dyoung 	u32 reg_offset = (vf_number < 32) ? 0 : 1;
    511   1.1   dyoung 	u32 vf_shift = vf_number % 32;
    512   1.1   dyoung 	u32 vflre = 0;
    513   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    514   1.1   dyoung 
    515   1.1   dyoung 	DEBUGFUNC("ixgbe_check_for_rst_pf");
    516   1.1   dyoung 
    517   1.1   dyoung 	switch (hw->mac.type) {
    518   1.1   dyoung 	case ixgbe_mac_82599EB:
    519   1.1   dyoung 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
    520   1.1   dyoung 		break;
    521   1.4  msaitoh 	case ixgbe_mac_X550:
    522   1.4  msaitoh 	case ixgbe_mac_X550EM_x:
    523   1.7  msaitoh 	case ixgbe_mac_X550EM_a:
    524   1.2  msaitoh 	case ixgbe_mac_X540:
    525   1.2  msaitoh 		vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
    526   1.2  msaitoh 		break;
    527   1.1   dyoung 	default:
    528   1.1   dyoung 		break;
    529   1.1   dyoung 	}
    530   1.1   dyoung 
    531   1.1   dyoung 	if (vflre & (1 << vf_shift)) {
    532   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    533   1.1   dyoung 		IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
    534   1.8  msaitoh 		hw->mbx.stats.rsts.ev_count++;
    535   1.1   dyoung 	}
    536   1.1   dyoung 
    537   1.1   dyoung 	return ret_val;
    538   1.1   dyoung }
    539   1.1   dyoung 
    540   1.1   dyoung /**
    541   1.1   dyoung  *  ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
    542   1.1   dyoung  *  @hw: pointer to the HW structure
    543   1.1   dyoung  *  @vf_number: the VF index
    544   1.1   dyoung  *
    545   1.1   dyoung  *  return SUCCESS if we obtained the mailbox lock
    546   1.1   dyoung  **/
    547   1.1   dyoung static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
    548   1.1   dyoung {
    549   1.1   dyoung 	s32 ret_val = IXGBE_ERR_MBX;
    550   1.1   dyoung 	u32 p2v_mailbox;
    551   1.1   dyoung 
    552   1.1   dyoung 	DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
    553   1.1   dyoung 
    554   1.1   dyoung 	/* Take ownership of the buffer */
    555   1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
    556   1.1   dyoung 
    557   1.1   dyoung 	/* reserve mailbox for vf use */
    558   1.1   dyoung 	p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
    559   1.1   dyoung 	if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
    560   1.1   dyoung 		ret_val = IXGBE_SUCCESS;
    561   1.4  msaitoh 	else
    562   1.4  msaitoh 		ERROR_REPORT2(IXGBE_ERROR_POLLING,
    563   1.4  msaitoh 			   "Failed to obtain mailbox lock for VF%d", vf_number);
    564   1.4  msaitoh 
    565   1.1   dyoung 
    566   1.1   dyoung 	return ret_val;
    567   1.1   dyoung }
    568   1.1   dyoung 
    569   1.1   dyoung /**
    570   1.1   dyoung  *  ixgbe_write_mbx_pf - Places a message in the mailbox
    571   1.1   dyoung  *  @hw: pointer to the HW structure
    572   1.1   dyoung  *  @msg: The message buffer
    573   1.1   dyoung  *  @size: Length of buffer
    574   1.1   dyoung  *  @vf_number: the VF index
    575   1.1   dyoung  *
    576   1.1   dyoung  *  returns SUCCESS if it successfully copied message into the buffer
    577   1.1   dyoung  **/
    578   1.1   dyoung static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    579   1.2  msaitoh 			      u16 vf_number)
    580   1.1   dyoung {
    581   1.1   dyoung 	s32 ret_val;
    582   1.1   dyoung 	u16 i;
    583   1.1   dyoung 
    584   1.1   dyoung 	DEBUGFUNC("ixgbe_write_mbx_pf");
    585   1.1   dyoung 
    586   1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    587   1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
    588   1.1   dyoung 	if (ret_val)
    589   1.1   dyoung 		goto out_no_write;
    590   1.1   dyoung 
    591   1.1   dyoung 	/* flush msg and acks as we are overwriting the message buffer */
    592   1.1   dyoung 	ixgbe_check_for_msg_pf(hw, vf_number);
    593   1.1   dyoung 	ixgbe_check_for_ack_pf(hw, vf_number);
    594   1.1   dyoung 
    595   1.1   dyoung 	/* copy the caller specified message to the mailbox memory buffer */
    596   1.1   dyoung 	for (i = 0; i < size; i++)
    597   1.1   dyoung 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
    598   1.1   dyoung 
    599   1.1   dyoung 	/* Interrupt VF to tell it a message has been sent and release buffer*/
    600   1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
    601   1.1   dyoung 
    602   1.1   dyoung 	/* update stats */
    603   1.8  msaitoh 	hw->mbx.stats.msgs_tx.ev_count++;
    604   1.1   dyoung 
    605   1.1   dyoung out_no_write:
    606   1.1   dyoung 	return ret_val;
    607   1.1   dyoung 
    608   1.1   dyoung }
    609   1.1   dyoung 
    610   1.1   dyoung /**
    611   1.1   dyoung  *  ixgbe_read_mbx_pf - Read a message from the mailbox
    612   1.1   dyoung  *  @hw: pointer to the HW structure
    613   1.1   dyoung  *  @msg: The message buffer
    614   1.1   dyoung  *  @size: Length of buffer
    615   1.1   dyoung  *  @vf_number: the VF index
    616   1.1   dyoung  *
    617   1.1   dyoung  *  This function copies a message from the mailbox buffer to the caller's
    618   1.1   dyoung  *  memory buffer.  The presumption is that the caller knows that there was
    619   1.1   dyoung  *  a message due to a VF request so no polling for message is needed.
    620   1.1   dyoung  **/
    621   1.1   dyoung static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
    622   1.2  msaitoh 			     u16 vf_number)
    623   1.1   dyoung {
    624   1.1   dyoung 	s32 ret_val;
    625   1.1   dyoung 	u16 i;
    626   1.1   dyoung 
    627   1.1   dyoung 	DEBUGFUNC("ixgbe_read_mbx_pf");
    628   1.1   dyoung 
    629   1.1   dyoung 	/* lock the mailbox to prevent pf/vf race condition */
    630   1.1   dyoung 	ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
    631   1.1   dyoung 	if (ret_val)
    632   1.1   dyoung 		goto out_no_read;
    633   1.1   dyoung 
    634   1.1   dyoung 	/* copy the message to the mailbox memory buffer */
    635   1.1   dyoung 	for (i = 0; i < size; i++)
    636   1.1   dyoung 		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
    637   1.1   dyoung 
    638   1.1   dyoung 	/* Acknowledge the message and release buffer */
    639   1.1   dyoung 	IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
    640   1.1   dyoung 
    641   1.1   dyoung 	/* update stats */
    642   1.8  msaitoh 	hw->mbx.stats.msgs_rx.ev_count++;
    643   1.1   dyoung 
    644   1.1   dyoung out_no_read:
    645   1.1   dyoung 	return ret_val;
    646   1.1   dyoung }
    647   1.1   dyoung 
    648   1.1   dyoung /**
    649  1.11  msaitoh  *  ixgbe_clear_mbx_pf - Clear Mailbox Memory
    650  1.11  msaitoh  *  @hw: pointer to the HW structure
    651  1.11  msaitoh  *  @vf_number: the VF index
    652  1.11  msaitoh  *
    653  1.11  msaitoh  *  Set VFMBMEM of given VF to 0x0.
    654  1.11  msaitoh  **/
    655  1.11  msaitoh static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_number)
    656  1.11  msaitoh {
    657  1.11  msaitoh 	u16 mbx_size = hw->mbx.size;
    658  1.11  msaitoh 	u16 i;
    659  1.11  msaitoh 
    660  1.11  msaitoh 	if (vf_number > 63)
    661  1.11  msaitoh 		return IXGBE_ERR_PARAM;
    662  1.11  msaitoh 
    663  1.11  msaitoh 	for (i = 0; i < mbx_size; ++i)
    664  1.11  msaitoh 		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, 0x0);
    665  1.11  msaitoh 
    666  1.11  msaitoh 	return IXGBE_SUCCESS;
    667  1.11  msaitoh }
    668  1.11  msaitoh 
    669  1.11  msaitoh /**
    670   1.1   dyoung  *  ixgbe_init_mbx_params_pf - set initial values for pf mailbox
    671   1.1   dyoung  *  @hw: pointer to the HW structure
    672   1.1   dyoung  *
    673   1.1   dyoung  *  Initializes the hw->mbx struct to correct values for pf mailbox
    674   1.1   dyoung  */
    675   1.1   dyoung void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
    676   1.1   dyoung {
    677   1.1   dyoung 	struct ixgbe_mbx_info *mbx = &hw->mbx;
    678   1.1   dyoung 
    679   1.2  msaitoh 	if (hw->mac.type != ixgbe_mac_82599EB &&
    680   1.4  msaitoh 	    hw->mac.type != ixgbe_mac_X550 &&
    681   1.4  msaitoh 	    hw->mac.type != ixgbe_mac_X550EM_x &&
    682   1.7  msaitoh 	    hw->mac.type != ixgbe_mac_X550EM_a &&
    683   1.2  msaitoh 	    hw->mac.type != ixgbe_mac_X540)
    684   1.1   dyoung 		return;
    685   1.1   dyoung 
    686   1.1   dyoung 	mbx->timeout = 0;
    687   1.1   dyoung 	mbx->usec_delay = 0;
    688   1.1   dyoung 
    689   1.1   dyoung 	mbx->size = IXGBE_VFMAILBOX_SIZE;
    690   1.1   dyoung 
    691   1.1   dyoung 	mbx->ops.read = ixgbe_read_mbx_pf;
    692   1.1   dyoung 	mbx->ops.write = ixgbe_write_mbx_pf;
    693   1.1   dyoung 	mbx->ops.read_posted = ixgbe_read_posted_mbx;
    694   1.1   dyoung 	mbx->ops.write_posted = ixgbe_write_posted_mbx;
    695   1.1   dyoung 	mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
    696   1.1   dyoung 	mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
    697   1.1   dyoung 	mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
    698  1.11  msaitoh 	mbx->ops.clear = ixgbe_clear_mbx_pf;
    699   1.1   dyoung 
    700   1.8  msaitoh 	mbx->stats.msgs_tx.ev_count = 0;
    701   1.8  msaitoh 	mbx->stats.msgs_rx.ev_count = 0;
    702   1.8  msaitoh 	mbx->stats.reqs.ev_count = 0;
    703   1.8  msaitoh 	mbx->stats.acks.ev_count = 0;
    704   1.8  msaitoh 	mbx->stats.rsts.ev_count = 0;
    705   1.1   dyoung }
    706