175eba5b6SRobert Mustacchi /****************************************************************************** 275eba5b6SRobert Mustacchi 3*42cc51e0SRobert Mustacchi Copyright (c) 2001-2015, Intel Corporation 475eba5b6SRobert Mustacchi All rights reserved. 575eba5b6SRobert Mustacchi 675eba5b6SRobert Mustacchi Redistribution and use in source and binary forms, with or without 775eba5b6SRobert Mustacchi modification, are permitted provided that the following conditions are met: 875eba5b6SRobert Mustacchi 975eba5b6SRobert Mustacchi 1. Redistributions of source code must retain the above copyright notice, 1075eba5b6SRobert Mustacchi this list of conditions and the following disclaimer. 1175eba5b6SRobert Mustacchi 1275eba5b6SRobert Mustacchi 2. Redistributions in binary form must reproduce the above copyright 1375eba5b6SRobert Mustacchi notice, this list of conditions and the following disclaimer in the 1475eba5b6SRobert Mustacchi documentation and/or other materials provided with the distribution. 1575eba5b6SRobert Mustacchi 1675eba5b6SRobert Mustacchi 3. Neither the name of the Intel Corporation nor the names of its 1775eba5b6SRobert Mustacchi contributors may be used to endorse or promote products derived from 1875eba5b6SRobert Mustacchi this software without specific prior written permission. 1975eba5b6SRobert Mustacchi 2075eba5b6SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2175eba5b6SRobert Mustacchi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2275eba5b6SRobert Mustacchi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2375eba5b6SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2475eba5b6SRobert Mustacchi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2575eba5b6SRobert Mustacchi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2675eba5b6SRobert Mustacchi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2775eba5b6SRobert Mustacchi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2875eba5b6SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2975eba5b6SRobert Mustacchi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3075eba5b6SRobert Mustacchi POSSIBILITY OF SUCH DAMAGE. 3175eba5b6SRobert Mustacchi 3275eba5b6SRobert Mustacchi ******************************************************************************/ 3375eba5b6SRobert Mustacchi /*$FreeBSD$*/ 3475eba5b6SRobert Mustacchi 3575eba5b6SRobert Mustacchi #include "e1000_mbx.h" 3675eba5b6SRobert Mustacchi 3775eba5b6SRobert Mustacchi /** 3875eba5b6SRobert Mustacchi * e1000_null_mbx_check_for_flag - No-op function, return 0 3975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 4075eba5b6SRobert Mustacchi **/ 41c124a83eSRobert Mustacchi static s32 e1000_null_mbx_check_for_flag(struct e1000_hw E1000_UNUSEDARG *hw, 42c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id) 4375eba5b6SRobert Mustacchi { 4475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_null_mbx_check_flag"); 4575eba5b6SRobert Mustacchi 4675eba5b6SRobert Mustacchi return E1000_SUCCESS; 4775eba5b6SRobert Mustacchi } 4875eba5b6SRobert Mustacchi 4975eba5b6SRobert Mustacchi /** 5075eba5b6SRobert Mustacchi * e1000_null_mbx_transact - No-op function, return 0 5175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 5275eba5b6SRobert Mustacchi **/ 53c124a83eSRobert Mustacchi static s32 e1000_null_mbx_transact(struct e1000_hw E1000_UNUSEDARG *hw, 54c124a83eSRobert Mustacchi u32 E1000_UNUSEDARG *msg, 55c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG size, 56c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id) 5775eba5b6SRobert Mustacchi { 5875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_null_mbx_rw_msg"); 5975eba5b6SRobert Mustacchi 6075eba5b6SRobert Mustacchi return E1000_SUCCESS; 6175eba5b6SRobert Mustacchi } 6275eba5b6SRobert Mustacchi 6375eba5b6SRobert Mustacchi /** 6475eba5b6SRobert Mustacchi * e1000_read_mbx - Reads a message from the mailbox 6575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 6675eba5b6SRobert Mustacchi * @msg: The message buffer 6775eba5b6SRobert Mustacchi * @size: Length of buffer 6875eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to read 6975eba5b6SRobert Mustacchi * 7075eba5b6SRobert Mustacchi * returns SUCCESS if it successfuly read message from buffer 7175eba5b6SRobert Mustacchi **/ 7275eba5b6SRobert Mustacchi s32 e1000_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 7375eba5b6SRobert Mustacchi { 7475eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 7575eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 7675eba5b6SRobert Mustacchi 7775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_mbx"); 7875eba5b6SRobert Mustacchi 7975eba5b6SRobert Mustacchi /* limit read to size of mailbox */ 8075eba5b6SRobert Mustacchi if (size > mbx->size) 8175eba5b6SRobert Mustacchi size = mbx->size; 8275eba5b6SRobert Mustacchi 8375eba5b6SRobert Mustacchi if (mbx->ops.read) 8475eba5b6SRobert Mustacchi ret_val = mbx->ops.read(hw, msg, size, mbx_id); 8575eba5b6SRobert Mustacchi 8675eba5b6SRobert Mustacchi return ret_val; 8775eba5b6SRobert Mustacchi } 8875eba5b6SRobert Mustacchi 8975eba5b6SRobert Mustacchi /** 9075eba5b6SRobert Mustacchi * e1000_write_mbx - Write a message to the mailbox 9175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 9275eba5b6SRobert Mustacchi * @msg: The message buffer 9375eba5b6SRobert Mustacchi * @size: Length of buffer 9475eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write 9575eba5b6SRobert Mustacchi * 9675eba5b6SRobert Mustacchi * returns SUCCESS if it successfully copied message into the buffer 9775eba5b6SRobert Mustacchi **/ 9875eba5b6SRobert Mustacchi s32 e1000_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 9975eba5b6SRobert Mustacchi { 10075eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 10175eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 10275eba5b6SRobert Mustacchi 10375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_mbx"); 10475eba5b6SRobert Mustacchi 10575eba5b6SRobert Mustacchi if (size > mbx->size) 10675eba5b6SRobert Mustacchi ret_val = -E1000_ERR_MBX; 10775eba5b6SRobert Mustacchi 10875eba5b6SRobert Mustacchi else if (mbx->ops.write) 10975eba5b6SRobert Mustacchi ret_val = mbx->ops.write(hw, msg, size, mbx_id); 11075eba5b6SRobert Mustacchi 11175eba5b6SRobert Mustacchi return ret_val; 11275eba5b6SRobert Mustacchi } 11375eba5b6SRobert Mustacchi 11475eba5b6SRobert Mustacchi /** 11575eba5b6SRobert Mustacchi * e1000_check_for_msg - checks to see if someone sent us mail 11675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 11775eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check 11875eba5b6SRobert Mustacchi * 11975eba5b6SRobert Mustacchi * returns SUCCESS if the Status bit was found or else ERR_MBX 12075eba5b6SRobert Mustacchi **/ 12175eba5b6SRobert Mustacchi s32 e1000_check_for_msg(struct e1000_hw *hw, u16 mbx_id) 12275eba5b6SRobert Mustacchi { 12375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 12475eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 12575eba5b6SRobert Mustacchi 12675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_msg"); 12775eba5b6SRobert Mustacchi 12875eba5b6SRobert Mustacchi if (mbx->ops.check_for_msg) 12975eba5b6SRobert Mustacchi ret_val = mbx->ops.check_for_msg(hw, mbx_id); 13075eba5b6SRobert Mustacchi 13175eba5b6SRobert Mustacchi return ret_val; 13275eba5b6SRobert Mustacchi } 13375eba5b6SRobert Mustacchi 13475eba5b6SRobert Mustacchi /** 13575eba5b6SRobert Mustacchi * e1000_check_for_ack - checks to see if someone sent us ACK 13675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 13775eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check 13875eba5b6SRobert Mustacchi * 13975eba5b6SRobert Mustacchi * returns SUCCESS if the Status bit was found or else ERR_MBX 14075eba5b6SRobert Mustacchi **/ 14175eba5b6SRobert Mustacchi s32 e1000_check_for_ack(struct e1000_hw *hw, u16 mbx_id) 14275eba5b6SRobert Mustacchi { 14375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 14475eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 14575eba5b6SRobert Mustacchi 14675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_ack"); 14775eba5b6SRobert Mustacchi 14875eba5b6SRobert Mustacchi if (mbx->ops.check_for_ack) 14975eba5b6SRobert Mustacchi ret_val = mbx->ops.check_for_ack(hw, mbx_id); 15075eba5b6SRobert Mustacchi 15175eba5b6SRobert Mustacchi return ret_val; 15275eba5b6SRobert Mustacchi } 15375eba5b6SRobert Mustacchi 15475eba5b6SRobert Mustacchi /** 15575eba5b6SRobert Mustacchi * e1000_check_for_rst - checks to see if other side has reset 15675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 15775eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check 15875eba5b6SRobert Mustacchi * 15975eba5b6SRobert Mustacchi * returns SUCCESS if the Status bit was found or else ERR_MBX 16075eba5b6SRobert Mustacchi **/ 16175eba5b6SRobert Mustacchi s32 e1000_check_for_rst(struct e1000_hw *hw, u16 mbx_id) 16275eba5b6SRobert Mustacchi { 16375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 16475eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 16575eba5b6SRobert Mustacchi 16675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_rst"); 16775eba5b6SRobert Mustacchi 16875eba5b6SRobert Mustacchi if (mbx->ops.check_for_rst) 16975eba5b6SRobert Mustacchi ret_val = mbx->ops.check_for_rst(hw, mbx_id); 17075eba5b6SRobert Mustacchi 17175eba5b6SRobert Mustacchi return ret_val; 17275eba5b6SRobert Mustacchi } 17375eba5b6SRobert Mustacchi 17475eba5b6SRobert Mustacchi /** 17575eba5b6SRobert Mustacchi * e1000_poll_for_msg - Wait for message notification 17675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 17775eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write 17875eba5b6SRobert Mustacchi * 17975eba5b6SRobert Mustacchi * returns SUCCESS if it successfully received a message notification 18075eba5b6SRobert Mustacchi **/ 18175eba5b6SRobert Mustacchi static s32 e1000_poll_for_msg(struct e1000_hw *hw, u16 mbx_id) 18275eba5b6SRobert Mustacchi { 18375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 18475eba5b6SRobert Mustacchi int countdown = mbx->timeout; 18575eba5b6SRobert Mustacchi 18675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_poll_for_msg"); 18775eba5b6SRobert Mustacchi 18875eba5b6SRobert Mustacchi if (!countdown || !mbx->ops.check_for_msg) 18975eba5b6SRobert Mustacchi goto out; 19075eba5b6SRobert Mustacchi 19175eba5b6SRobert Mustacchi while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { 19275eba5b6SRobert Mustacchi countdown--; 19375eba5b6SRobert Mustacchi if (!countdown) 19475eba5b6SRobert Mustacchi break; 19575eba5b6SRobert Mustacchi usec_delay(mbx->usec_delay); 19675eba5b6SRobert Mustacchi } 19775eba5b6SRobert Mustacchi 19875eba5b6SRobert Mustacchi /* if we failed, all future posted messages fail until reset */ 19975eba5b6SRobert Mustacchi if (!countdown) 20075eba5b6SRobert Mustacchi mbx->timeout = 0; 20175eba5b6SRobert Mustacchi out: 20275eba5b6SRobert Mustacchi return countdown ? E1000_SUCCESS : -E1000_ERR_MBX; 20375eba5b6SRobert Mustacchi } 20475eba5b6SRobert Mustacchi 20575eba5b6SRobert Mustacchi /** 20675eba5b6SRobert Mustacchi * e1000_poll_for_ack - Wait for message acknowledgement 20775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 20875eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write 20975eba5b6SRobert Mustacchi * 21075eba5b6SRobert Mustacchi * returns SUCCESS if it successfully received a message acknowledgement 21175eba5b6SRobert Mustacchi **/ 21275eba5b6SRobert Mustacchi static s32 e1000_poll_for_ack(struct e1000_hw *hw, u16 mbx_id) 21375eba5b6SRobert Mustacchi { 21475eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 21575eba5b6SRobert Mustacchi int countdown = mbx->timeout; 21675eba5b6SRobert Mustacchi 21775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_poll_for_ack"); 21875eba5b6SRobert Mustacchi 21975eba5b6SRobert Mustacchi if (!countdown || !mbx->ops.check_for_ack) 22075eba5b6SRobert Mustacchi goto out; 22175eba5b6SRobert Mustacchi 22275eba5b6SRobert Mustacchi while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { 22375eba5b6SRobert Mustacchi countdown--; 22475eba5b6SRobert Mustacchi if (!countdown) 22575eba5b6SRobert Mustacchi break; 22675eba5b6SRobert Mustacchi usec_delay(mbx->usec_delay); 22775eba5b6SRobert Mustacchi } 22875eba5b6SRobert Mustacchi 22975eba5b6SRobert Mustacchi /* if we failed, all future posted messages fail until reset */ 23075eba5b6SRobert Mustacchi if (!countdown) 23175eba5b6SRobert Mustacchi mbx->timeout = 0; 23275eba5b6SRobert Mustacchi out: 23375eba5b6SRobert Mustacchi return countdown ? E1000_SUCCESS : -E1000_ERR_MBX; 23475eba5b6SRobert Mustacchi } 23575eba5b6SRobert Mustacchi 23675eba5b6SRobert Mustacchi /** 23775eba5b6SRobert Mustacchi * e1000_read_posted_mbx - Wait for message notification and receive message 23875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 23975eba5b6SRobert Mustacchi * @msg: The message buffer 24075eba5b6SRobert Mustacchi * @size: Length of buffer 24175eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write 24275eba5b6SRobert Mustacchi * 24375eba5b6SRobert Mustacchi * returns SUCCESS if it successfully received a message notification and 24475eba5b6SRobert Mustacchi * copied it into the receive buffer. 24575eba5b6SRobert Mustacchi **/ 24675eba5b6SRobert Mustacchi s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 24775eba5b6SRobert Mustacchi { 24875eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 24975eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 25075eba5b6SRobert Mustacchi 25175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_posted_mbx"); 25275eba5b6SRobert Mustacchi 25375eba5b6SRobert Mustacchi if (!mbx->ops.read) 25475eba5b6SRobert Mustacchi goto out; 25575eba5b6SRobert Mustacchi 25675eba5b6SRobert Mustacchi ret_val = e1000_poll_for_msg(hw, mbx_id); 25775eba5b6SRobert Mustacchi 25875eba5b6SRobert Mustacchi /* if ack received read message, otherwise we timed out */ 25975eba5b6SRobert Mustacchi if (!ret_val) 26075eba5b6SRobert Mustacchi ret_val = mbx->ops.read(hw, msg, size, mbx_id); 26175eba5b6SRobert Mustacchi out: 26275eba5b6SRobert Mustacchi return ret_val; 26375eba5b6SRobert Mustacchi } 26475eba5b6SRobert Mustacchi 26575eba5b6SRobert Mustacchi /** 26675eba5b6SRobert Mustacchi * e1000_write_posted_mbx - Write a message to the mailbox, wait for ack 26775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 26875eba5b6SRobert Mustacchi * @msg: The message buffer 26975eba5b6SRobert Mustacchi * @size: Length of buffer 27075eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write 27175eba5b6SRobert Mustacchi * 27275eba5b6SRobert Mustacchi * returns SUCCESS if it successfully copied message into the buffer and 27375eba5b6SRobert Mustacchi * received an ack to that message within delay * timeout period 27475eba5b6SRobert Mustacchi **/ 27575eba5b6SRobert Mustacchi s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id) 27675eba5b6SRobert Mustacchi { 27775eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 27875eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 27975eba5b6SRobert Mustacchi 28075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_posted_mbx"); 28175eba5b6SRobert Mustacchi 28275eba5b6SRobert Mustacchi /* exit if either we can't write or there isn't a defined timeout */ 28375eba5b6SRobert Mustacchi if (!mbx->ops.write || !mbx->timeout) 28475eba5b6SRobert Mustacchi goto out; 28575eba5b6SRobert Mustacchi 28675eba5b6SRobert Mustacchi /* send msg */ 28775eba5b6SRobert Mustacchi ret_val = mbx->ops.write(hw, msg, size, mbx_id); 28875eba5b6SRobert Mustacchi 28975eba5b6SRobert Mustacchi /* if msg sent wait until we receive an ack */ 29075eba5b6SRobert Mustacchi if (!ret_val) 29175eba5b6SRobert Mustacchi ret_val = e1000_poll_for_ack(hw, mbx_id); 29275eba5b6SRobert Mustacchi out: 29375eba5b6SRobert Mustacchi return ret_val; 29475eba5b6SRobert Mustacchi } 29575eba5b6SRobert Mustacchi 29675eba5b6SRobert Mustacchi /** 29775eba5b6SRobert Mustacchi * e1000_init_mbx_ops_generic - Initialize mbx function pointers 29875eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 29975eba5b6SRobert Mustacchi * 30075eba5b6SRobert Mustacchi * Sets the function pointers to no-op functions 30175eba5b6SRobert Mustacchi **/ 30275eba5b6SRobert Mustacchi void e1000_init_mbx_ops_generic(struct e1000_hw *hw) 30375eba5b6SRobert Mustacchi { 30475eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 30575eba5b6SRobert Mustacchi mbx->ops.init_params = e1000_null_ops_generic; 30675eba5b6SRobert Mustacchi mbx->ops.read = e1000_null_mbx_transact; 30775eba5b6SRobert Mustacchi mbx->ops.write = e1000_null_mbx_transact; 30875eba5b6SRobert Mustacchi mbx->ops.check_for_msg = e1000_null_mbx_check_for_flag; 30975eba5b6SRobert Mustacchi mbx->ops.check_for_ack = e1000_null_mbx_check_for_flag; 31075eba5b6SRobert Mustacchi mbx->ops.check_for_rst = e1000_null_mbx_check_for_flag; 31175eba5b6SRobert Mustacchi mbx->ops.read_posted = e1000_read_posted_mbx; 31275eba5b6SRobert Mustacchi mbx->ops.write_posted = e1000_write_posted_mbx; 31375eba5b6SRobert Mustacchi } 31475eba5b6SRobert Mustacchi 31575eba5b6SRobert Mustacchi /** 31675eba5b6SRobert Mustacchi * e1000_read_v2p_mailbox - read v2p mailbox 31775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 31875eba5b6SRobert Mustacchi * 31975eba5b6SRobert Mustacchi * This function is used to read the v2p mailbox without losing the read to 32075eba5b6SRobert Mustacchi * clear status bits. 32175eba5b6SRobert Mustacchi **/ 32275eba5b6SRobert Mustacchi static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw) 32375eba5b6SRobert Mustacchi { 32475eba5b6SRobert Mustacchi u32 v2p_mailbox = E1000_READ_REG(hw, E1000_V2PMAILBOX(0)); 32575eba5b6SRobert Mustacchi 32675eba5b6SRobert Mustacchi v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox; 32775eba5b6SRobert Mustacchi hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS; 32875eba5b6SRobert Mustacchi 32975eba5b6SRobert Mustacchi return v2p_mailbox; 33075eba5b6SRobert Mustacchi } 33175eba5b6SRobert Mustacchi 33275eba5b6SRobert Mustacchi /** 33375eba5b6SRobert Mustacchi * e1000_check_for_bit_vf - Determine if a status bit was set 33475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 33575eba5b6SRobert Mustacchi * @mask: bitmask for bits to be tested and cleared 33675eba5b6SRobert Mustacchi * 33775eba5b6SRobert Mustacchi * This function is used to check for the read to clear bits within 33875eba5b6SRobert Mustacchi * the V2P mailbox. 33975eba5b6SRobert Mustacchi **/ 34075eba5b6SRobert Mustacchi static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask) 34175eba5b6SRobert Mustacchi { 34275eba5b6SRobert Mustacchi u32 v2p_mailbox = e1000_read_v2p_mailbox(hw); 34375eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 34475eba5b6SRobert Mustacchi 34575eba5b6SRobert Mustacchi if (v2p_mailbox & mask) 34675eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 34775eba5b6SRobert Mustacchi 34875eba5b6SRobert Mustacchi hw->dev_spec.vf.v2p_mailbox &= ~mask; 34975eba5b6SRobert Mustacchi 35075eba5b6SRobert Mustacchi return ret_val; 35175eba5b6SRobert Mustacchi } 35275eba5b6SRobert Mustacchi 35375eba5b6SRobert Mustacchi /** 35475eba5b6SRobert Mustacchi * e1000_check_for_msg_vf - checks to see if the PF has sent mail 35575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 35675eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check 35775eba5b6SRobert Mustacchi * 35875eba5b6SRobert Mustacchi * returns SUCCESS if the PF has set the Status bit or else ERR_MBX 35975eba5b6SRobert Mustacchi **/ 360c124a83eSRobert Mustacchi static s32 e1000_check_for_msg_vf(struct e1000_hw *hw, 361c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id) 36275eba5b6SRobert Mustacchi { 36375eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 36475eba5b6SRobert Mustacchi 36575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_msg_vf"); 36675eba5b6SRobert Mustacchi 36775eba5b6SRobert Mustacchi if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) { 36875eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 36975eba5b6SRobert Mustacchi hw->mbx.stats.reqs++; 37075eba5b6SRobert Mustacchi } 37175eba5b6SRobert Mustacchi 37275eba5b6SRobert Mustacchi return ret_val; 37375eba5b6SRobert Mustacchi } 37475eba5b6SRobert Mustacchi 37575eba5b6SRobert Mustacchi /** 37675eba5b6SRobert Mustacchi * e1000_check_for_ack_vf - checks to see if the PF has ACK'd 37775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 37875eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check 37975eba5b6SRobert Mustacchi * 38075eba5b6SRobert Mustacchi * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX 38175eba5b6SRobert Mustacchi **/ 382c124a83eSRobert Mustacchi static s32 e1000_check_for_ack_vf(struct e1000_hw *hw, 383c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id) 38475eba5b6SRobert Mustacchi { 38575eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 38675eba5b6SRobert Mustacchi 38775eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_ack_vf"); 38875eba5b6SRobert Mustacchi 38975eba5b6SRobert Mustacchi if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) { 39075eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 39175eba5b6SRobert Mustacchi hw->mbx.stats.acks++; 39275eba5b6SRobert Mustacchi } 39375eba5b6SRobert Mustacchi 39475eba5b6SRobert Mustacchi return ret_val; 39575eba5b6SRobert Mustacchi } 39675eba5b6SRobert Mustacchi 39775eba5b6SRobert Mustacchi /** 39875eba5b6SRobert Mustacchi * e1000_check_for_rst_vf - checks to see if the PF has reset 39975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 40075eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to check 40175eba5b6SRobert Mustacchi * 40275eba5b6SRobert Mustacchi * returns TRUE if the PF has set the reset done bit or else FALSE 40375eba5b6SRobert Mustacchi **/ 404c124a83eSRobert Mustacchi static s32 e1000_check_for_rst_vf(struct e1000_hw *hw, 405c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id) 40675eba5b6SRobert Mustacchi { 40775eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 40875eba5b6SRobert Mustacchi 40975eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_rst_vf"); 41075eba5b6SRobert Mustacchi 41175eba5b6SRobert Mustacchi if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD | 41275eba5b6SRobert Mustacchi E1000_V2PMAILBOX_RSTI))) { 41375eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 41475eba5b6SRobert Mustacchi hw->mbx.stats.rsts++; 41575eba5b6SRobert Mustacchi } 41675eba5b6SRobert Mustacchi 41775eba5b6SRobert Mustacchi return ret_val; 41875eba5b6SRobert Mustacchi } 41975eba5b6SRobert Mustacchi 42075eba5b6SRobert Mustacchi /** 42175eba5b6SRobert Mustacchi * e1000_obtain_mbx_lock_vf - obtain mailbox lock 42275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 42375eba5b6SRobert Mustacchi * 42475eba5b6SRobert Mustacchi * return SUCCESS if we obtained the mailbox lock 42575eba5b6SRobert Mustacchi **/ 42675eba5b6SRobert Mustacchi static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw) 42775eba5b6SRobert Mustacchi { 42875eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 429*42cc51e0SRobert Mustacchi int count = 10; 43075eba5b6SRobert Mustacchi 43175eba5b6SRobert Mustacchi DEBUGFUNC("e1000_obtain_mbx_lock_vf"); 43275eba5b6SRobert Mustacchi 433*42cc51e0SRobert Mustacchi do { 43475eba5b6SRobert Mustacchi /* Take ownership of the buffer */ 43575eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_VFU); 43675eba5b6SRobert Mustacchi 43775eba5b6SRobert Mustacchi /* reserve mailbox for vf use */ 438*42cc51e0SRobert Mustacchi if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) { 43975eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 440*42cc51e0SRobert Mustacchi break; 441*42cc51e0SRobert Mustacchi } 442*42cc51e0SRobert Mustacchi usec_delay(1000); 443*42cc51e0SRobert Mustacchi } while (count-- > 0); 44475eba5b6SRobert Mustacchi 44575eba5b6SRobert Mustacchi return ret_val; 44675eba5b6SRobert Mustacchi } 44775eba5b6SRobert Mustacchi 44875eba5b6SRobert Mustacchi /** 44975eba5b6SRobert Mustacchi * e1000_write_mbx_vf - Write a message to the mailbox 45075eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 45175eba5b6SRobert Mustacchi * @msg: The message buffer 45275eba5b6SRobert Mustacchi * @size: Length of buffer 45375eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to write 45475eba5b6SRobert Mustacchi * 45575eba5b6SRobert Mustacchi * returns SUCCESS if it successfully copied message into the buffer 45675eba5b6SRobert Mustacchi **/ 45775eba5b6SRobert Mustacchi static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size, 458c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id) 45975eba5b6SRobert Mustacchi { 46075eba5b6SRobert Mustacchi s32 ret_val; 46175eba5b6SRobert Mustacchi u16 i; 46275eba5b6SRobert Mustacchi 46375eba5b6SRobert Mustacchi 46475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_mbx_vf"); 46575eba5b6SRobert Mustacchi 46675eba5b6SRobert Mustacchi /* lock the mailbox to prevent pf/vf race condition */ 46775eba5b6SRobert Mustacchi ret_val = e1000_obtain_mbx_lock_vf(hw); 46875eba5b6SRobert Mustacchi if (ret_val) 46975eba5b6SRobert Mustacchi goto out_no_write; 47075eba5b6SRobert Mustacchi 47175eba5b6SRobert Mustacchi /* flush msg and acks as we are overwriting the message buffer */ 47275eba5b6SRobert Mustacchi e1000_check_for_msg_vf(hw, 0); 47375eba5b6SRobert Mustacchi e1000_check_for_ack_vf(hw, 0); 47475eba5b6SRobert Mustacchi 47575eba5b6SRobert Mustacchi /* copy the caller specified message to the mailbox memory buffer */ 47675eba5b6SRobert Mustacchi for (i = 0; i < size; i++) 47775eba5b6SRobert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(0), i, msg[i]); 47875eba5b6SRobert Mustacchi 47975eba5b6SRobert Mustacchi /* update stats */ 48075eba5b6SRobert Mustacchi hw->mbx.stats.msgs_tx++; 48175eba5b6SRobert Mustacchi 48275eba5b6SRobert Mustacchi /* Drop VFU and interrupt the PF to tell it a message has been sent */ 48375eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_REQ); 48475eba5b6SRobert Mustacchi 48575eba5b6SRobert Mustacchi out_no_write: 48675eba5b6SRobert Mustacchi return ret_val; 48775eba5b6SRobert Mustacchi } 48875eba5b6SRobert Mustacchi 48975eba5b6SRobert Mustacchi /** 49075eba5b6SRobert Mustacchi * e1000_read_mbx_vf - Reads a message from the inbox intended for vf 49175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 49275eba5b6SRobert Mustacchi * @msg: The message buffer 49375eba5b6SRobert Mustacchi * @size: Length of buffer 49475eba5b6SRobert Mustacchi * @mbx_id: id of mailbox to read 49575eba5b6SRobert Mustacchi * 49675eba5b6SRobert Mustacchi * returns SUCCESS if it successfuly read message from buffer 49775eba5b6SRobert Mustacchi **/ 49875eba5b6SRobert Mustacchi static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size, 499c124a83eSRobert Mustacchi u16 E1000_UNUSEDARG mbx_id) 50075eba5b6SRobert Mustacchi { 50175eba5b6SRobert Mustacchi s32 ret_val = E1000_SUCCESS; 50275eba5b6SRobert Mustacchi u16 i; 50375eba5b6SRobert Mustacchi 50475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_mbx_vf"); 50575eba5b6SRobert Mustacchi 50675eba5b6SRobert Mustacchi /* lock the mailbox to prevent pf/vf race condition */ 50775eba5b6SRobert Mustacchi ret_val = e1000_obtain_mbx_lock_vf(hw); 50875eba5b6SRobert Mustacchi if (ret_val) 50975eba5b6SRobert Mustacchi goto out_no_read; 51075eba5b6SRobert Mustacchi 51175eba5b6SRobert Mustacchi /* copy the message from the mailbox memory buffer */ 51275eba5b6SRobert Mustacchi for (i = 0; i < size; i++) 51375eba5b6SRobert Mustacchi msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(0), i); 51475eba5b6SRobert Mustacchi 51575eba5b6SRobert Mustacchi /* Acknowledge receipt and release mailbox, then we're done */ 51675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_V2PMAILBOX(0), E1000_V2PMAILBOX_ACK); 51775eba5b6SRobert Mustacchi 51875eba5b6SRobert Mustacchi /* update stats */ 51975eba5b6SRobert Mustacchi hw->mbx.stats.msgs_rx++; 52075eba5b6SRobert Mustacchi 52175eba5b6SRobert Mustacchi out_no_read: 52275eba5b6SRobert Mustacchi return ret_val; 52375eba5b6SRobert Mustacchi } 52475eba5b6SRobert Mustacchi 52575eba5b6SRobert Mustacchi /** 52675eba5b6SRobert Mustacchi * e1000_init_mbx_params_vf - set initial values for vf mailbox 52775eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 52875eba5b6SRobert Mustacchi * 52975eba5b6SRobert Mustacchi * Initializes the hw->mbx struct to correct values for vf mailbox 53075eba5b6SRobert Mustacchi */ 53175eba5b6SRobert Mustacchi s32 e1000_init_mbx_params_vf(struct e1000_hw *hw) 53275eba5b6SRobert Mustacchi { 53375eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 53475eba5b6SRobert Mustacchi 53575eba5b6SRobert Mustacchi /* start mailbox as timed out and let the reset_hw call set the timeout 53675eba5b6SRobert Mustacchi * value to begin communications */ 53775eba5b6SRobert Mustacchi mbx->timeout = 0; 53875eba5b6SRobert Mustacchi mbx->usec_delay = E1000_VF_MBX_INIT_DELAY; 53975eba5b6SRobert Mustacchi 54075eba5b6SRobert Mustacchi mbx->size = E1000_VFMAILBOX_SIZE; 54175eba5b6SRobert Mustacchi 54275eba5b6SRobert Mustacchi mbx->ops.read = e1000_read_mbx_vf; 54375eba5b6SRobert Mustacchi mbx->ops.write = e1000_write_mbx_vf; 54475eba5b6SRobert Mustacchi mbx->ops.read_posted = e1000_read_posted_mbx; 54575eba5b6SRobert Mustacchi mbx->ops.write_posted = e1000_write_posted_mbx; 54675eba5b6SRobert Mustacchi mbx->ops.check_for_msg = e1000_check_for_msg_vf; 54775eba5b6SRobert Mustacchi mbx->ops.check_for_ack = e1000_check_for_ack_vf; 54875eba5b6SRobert Mustacchi mbx->ops.check_for_rst = e1000_check_for_rst_vf; 54975eba5b6SRobert Mustacchi 55075eba5b6SRobert Mustacchi mbx->stats.msgs_tx = 0; 55175eba5b6SRobert Mustacchi mbx->stats.msgs_rx = 0; 55275eba5b6SRobert Mustacchi mbx->stats.reqs = 0; 55375eba5b6SRobert Mustacchi mbx->stats.acks = 0; 55475eba5b6SRobert Mustacchi mbx->stats.rsts = 0; 55575eba5b6SRobert Mustacchi 55675eba5b6SRobert Mustacchi return E1000_SUCCESS; 55775eba5b6SRobert Mustacchi } 55875eba5b6SRobert Mustacchi 55975eba5b6SRobert Mustacchi static s32 e1000_check_for_bit_pf(struct e1000_hw *hw, u32 mask) 56075eba5b6SRobert Mustacchi { 56175eba5b6SRobert Mustacchi u32 mbvficr = E1000_READ_REG(hw, E1000_MBVFICR); 56275eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 56375eba5b6SRobert Mustacchi 56475eba5b6SRobert Mustacchi if (mbvficr & mask) { 56575eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 56675eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_MBVFICR, mask); 56775eba5b6SRobert Mustacchi } 56875eba5b6SRobert Mustacchi 56975eba5b6SRobert Mustacchi return ret_val; 57075eba5b6SRobert Mustacchi } 57175eba5b6SRobert Mustacchi 57275eba5b6SRobert Mustacchi /** 57375eba5b6SRobert Mustacchi * e1000_check_for_msg_pf - checks to see if the VF has sent mail 57475eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 57575eba5b6SRobert Mustacchi * @vf_number: the VF index 57675eba5b6SRobert Mustacchi * 57775eba5b6SRobert Mustacchi * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 57875eba5b6SRobert Mustacchi **/ 57975eba5b6SRobert Mustacchi static s32 e1000_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number) 58075eba5b6SRobert Mustacchi { 58175eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 58275eba5b6SRobert Mustacchi 58375eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_msg_pf"); 58475eba5b6SRobert Mustacchi 58575eba5b6SRobert Mustacchi if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) { 58675eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 58775eba5b6SRobert Mustacchi hw->mbx.stats.reqs++; 58875eba5b6SRobert Mustacchi } 58975eba5b6SRobert Mustacchi 59075eba5b6SRobert Mustacchi return ret_val; 59175eba5b6SRobert Mustacchi } 59275eba5b6SRobert Mustacchi 59375eba5b6SRobert Mustacchi /** 59475eba5b6SRobert Mustacchi * e1000_check_for_ack_pf - checks to see if the VF has ACKed 59575eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 59675eba5b6SRobert Mustacchi * @vf_number: the VF index 59775eba5b6SRobert Mustacchi * 59875eba5b6SRobert Mustacchi * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 59975eba5b6SRobert Mustacchi **/ 60075eba5b6SRobert Mustacchi static s32 e1000_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number) 60175eba5b6SRobert Mustacchi { 60275eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 60375eba5b6SRobert Mustacchi 60475eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_ack_pf"); 60575eba5b6SRobert Mustacchi 60675eba5b6SRobert Mustacchi if (!e1000_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) { 60775eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 60875eba5b6SRobert Mustacchi hw->mbx.stats.acks++; 60975eba5b6SRobert Mustacchi } 61075eba5b6SRobert Mustacchi 61175eba5b6SRobert Mustacchi return ret_val; 61275eba5b6SRobert Mustacchi } 61375eba5b6SRobert Mustacchi 61475eba5b6SRobert Mustacchi /** 61575eba5b6SRobert Mustacchi * e1000_check_for_rst_pf - checks to see if the VF has reset 61675eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 61775eba5b6SRobert Mustacchi * @vf_number: the VF index 61875eba5b6SRobert Mustacchi * 61975eba5b6SRobert Mustacchi * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 62075eba5b6SRobert Mustacchi **/ 62175eba5b6SRobert Mustacchi static s32 e1000_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number) 62275eba5b6SRobert Mustacchi { 62375eba5b6SRobert Mustacchi u32 vflre = E1000_READ_REG(hw, E1000_VFLRE); 62475eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 62575eba5b6SRobert Mustacchi 62675eba5b6SRobert Mustacchi DEBUGFUNC("e1000_check_for_rst_pf"); 62775eba5b6SRobert Mustacchi 62875eba5b6SRobert Mustacchi if (vflre & (1 << vf_number)) { 62975eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 63075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_VFLRE, (1 << vf_number)); 63175eba5b6SRobert Mustacchi hw->mbx.stats.rsts++; 63275eba5b6SRobert Mustacchi } 63375eba5b6SRobert Mustacchi 63475eba5b6SRobert Mustacchi return ret_val; 63575eba5b6SRobert Mustacchi } 63675eba5b6SRobert Mustacchi 63775eba5b6SRobert Mustacchi /** 63875eba5b6SRobert Mustacchi * e1000_obtain_mbx_lock_pf - obtain mailbox lock 63975eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 64075eba5b6SRobert Mustacchi * @vf_number: the VF index 64175eba5b6SRobert Mustacchi * 64275eba5b6SRobert Mustacchi * return SUCCESS if we obtained the mailbox lock 64375eba5b6SRobert Mustacchi **/ 64475eba5b6SRobert Mustacchi static s32 e1000_obtain_mbx_lock_pf(struct e1000_hw *hw, u16 vf_number) 64575eba5b6SRobert Mustacchi { 64675eba5b6SRobert Mustacchi s32 ret_val = -E1000_ERR_MBX; 64775eba5b6SRobert Mustacchi u32 p2v_mailbox; 648*42cc51e0SRobert Mustacchi int count = 10; 64975eba5b6SRobert Mustacchi 65075eba5b6SRobert Mustacchi DEBUGFUNC("e1000_obtain_mbx_lock_pf"); 65175eba5b6SRobert Mustacchi 652*42cc51e0SRobert Mustacchi do { 65375eba5b6SRobert Mustacchi /* Take ownership of the buffer */ 654*42cc51e0SRobert Mustacchi E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), 655*42cc51e0SRobert Mustacchi E1000_P2VMAILBOX_PFU); 65675eba5b6SRobert Mustacchi 657*42cc51e0SRobert Mustacchi /* reserve mailbox for pf use */ 65875eba5b6SRobert Mustacchi p2v_mailbox = E1000_READ_REG(hw, E1000_P2VMAILBOX(vf_number)); 659*42cc51e0SRobert Mustacchi if (p2v_mailbox & E1000_P2VMAILBOX_PFU) { 66075eba5b6SRobert Mustacchi ret_val = E1000_SUCCESS; 661*42cc51e0SRobert Mustacchi break; 662*42cc51e0SRobert Mustacchi } 663*42cc51e0SRobert Mustacchi usec_delay(1000); 664*42cc51e0SRobert Mustacchi } while (count-- > 0); 66575eba5b6SRobert Mustacchi 66675eba5b6SRobert Mustacchi return ret_val; 667*42cc51e0SRobert Mustacchi 66875eba5b6SRobert Mustacchi } 66975eba5b6SRobert Mustacchi 67075eba5b6SRobert Mustacchi /** 67175eba5b6SRobert Mustacchi * e1000_write_mbx_pf - Places a message in the mailbox 67275eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 67375eba5b6SRobert Mustacchi * @msg: The message buffer 67475eba5b6SRobert Mustacchi * @size: Length of buffer 67575eba5b6SRobert Mustacchi * @vf_number: the VF index 67675eba5b6SRobert Mustacchi * 67775eba5b6SRobert Mustacchi * returns SUCCESS if it successfully copied message into the buffer 67875eba5b6SRobert Mustacchi **/ 67975eba5b6SRobert Mustacchi static s32 e1000_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, 68075eba5b6SRobert Mustacchi u16 vf_number) 68175eba5b6SRobert Mustacchi { 68275eba5b6SRobert Mustacchi s32 ret_val; 68375eba5b6SRobert Mustacchi u16 i; 68475eba5b6SRobert Mustacchi 68575eba5b6SRobert Mustacchi DEBUGFUNC("e1000_write_mbx_pf"); 68675eba5b6SRobert Mustacchi 68775eba5b6SRobert Mustacchi /* lock the mailbox to prevent pf/vf race condition */ 68875eba5b6SRobert Mustacchi ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number); 68975eba5b6SRobert Mustacchi if (ret_val) 69075eba5b6SRobert Mustacchi goto out_no_write; 69175eba5b6SRobert Mustacchi 69275eba5b6SRobert Mustacchi /* flush msg and acks as we are overwriting the message buffer */ 69375eba5b6SRobert Mustacchi e1000_check_for_msg_pf(hw, vf_number); 69475eba5b6SRobert Mustacchi e1000_check_for_ack_pf(hw, vf_number); 69575eba5b6SRobert Mustacchi 69675eba5b6SRobert Mustacchi /* copy the caller specified message to the mailbox memory buffer */ 69775eba5b6SRobert Mustacchi for (i = 0; i < size; i++) 69875eba5b6SRobert Mustacchi E1000_WRITE_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i, msg[i]); 69975eba5b6SRobert Mustacchi 70075eba5b6SRobert Mustacchi /* Interrupt VF to tell it a message has been sent and release buffer*/ 70175eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS); 70275eba5b6SRobert Mustacchi 70375eba5b6SRobert Mustacchi /* update stats */ 70475eba5b6SRobert Mustacchi hw->mbx.stats.msgs_tx++; 70575eba5b6SRobert Mustacchi 70675eba5b6SRobert Mustacchi out_no_write: 70775eba5b6SRobert Mustacchi return ret_val; 70875eba5b6SRobert Mustacchi 70975eba5b6SRobert Mustacchi } 71075eba5b6SRobert Mustacchi 71175eba5b6SRobert Mustacchi /** 71275eba5b6SRobert Mustacchi * e1000_read_mbx_pf - Read a message from the mailbox 71375eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 71475eba5b6SRobert Mustacchi * @msg: The message buffer 71575eba5b6SRobert Mustacchi * @size: Length of buffer 71675eba5b6SRobert Mustacchi * @vf_number: the VF index 71775eba5b6SRobert Mustacchi * 71875eba5b6SRobert Mustacchi * This function copies a message from the mailbox buffer to the caller's 71975eba5b6SRobert Mustacchi * memory buffer. The presumption is that the caller knows that there was 72075eba5b6SRobert Mustacchi * a message due to a VF request so no polling for message is needed. 72175eba5b6SRobert Mustacchi **/ 72275eba5b6SRobert Mustacchi static s32 e1000_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size, 72375eba5b6SRobert Mustacchi u16 vf_number) 72475eba5b6SRobert Mustacchi { 72575eba5b6SRobert Mustacchi s32 ret_val; 72675eba5b6SRobert Mustacchi u16 i; 72775eba5b6SRobert Mustacchi 72875eba5b6SRobert Mustacchi DEBUGFUNC("e1000_read_mbx_pf"); 72975eba5b6SRobert Mustacchi 73075eba5b6SRobert Mustacchi /* lock the mailbox to prevent pf/vf race condition */ 73175eba5b6SRobert Mustacchi ret_val = e1000_obtain_mbx_lock_pf(hw, vf_number); 73275eba5b6SRobert Mustacchi if (ret_val) 73375eba5b6SRobert Mustacchi goto out_no_read; 73475eba5b6SRobert Mustacchi 73575eba5b6SRobert Mustacchi /* copy the message to the mailbox memory buffer */ 73675eba5b6SRobert Mustacchi for (i = 0; i < size; i++) 73775eba5b6SRobert Mustacchi msg[i] = E1000_READ_REG_ARRAY(hw, E1000_VMBMEM(vf_number), i); 73875eba5b6SRobert Mustacchi 73975eba5b6SRobert Mustacchi /* Acknowledge the message and release buffer */ 74075eba5b6SRobert Mustacchi E1000_WRITE_REG(hw, E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK); 74175eba5b6SRobert Mustacchi 74275eba5b6SRobert Mustacchi /* update stats */ 74375eba5b6SRobert Mustacchi hw->mbx.stats.msgs_rx++; 74475eba5b6SRobert Mustacchi 74575eba5b6SRobert Mustacchi out_no_read: 74675eba5b6SRobert Mustacchi return ret_val; 74775eba5b6SRobert Mustacchi } 74875eba5b6SRobert Mustacchi 74975eba5b6SRobert Mustacchi /** 75075eba5b6SRobert Mustacchi * e1000_init_mbx_params_pf - set initial values for pf mailbox 75175eba5b6SRobert Mustacchi * @hw: pointer to the HW structure 75275eba5b6SRobert Mustacchi * 75375eba5b6SRobert Mustacchi * Initializes the hw->mbx struct to correct values for pf mailbox 75475eba5b6SRobert Mustacchi */ 75575eba5b6SRobert Mustacchi s32 e1000_init_mbx_params_pf(struct e1000_hw *hw) 75675eba5b6SRobert Mustacchi { 75775eba5b6SRobert Mustacchi struct e1000_mbx_info *mbx = &hw->mbx; 75875eba5b6SRobert Mustacchi 75975eba5b6SRobert Mustacchi switch (hw->mac.type) { 76075eba5b6SRobert Mustacchi case e1000_82576: 76175eba5b6SRobert Mustacchi case e1000_i350: 762c124a83eSRobert Mustacchi case e1000_i354: 76375eba5b6SRobert Mustacchi mbx->timeout = 0; 76475eba5b6SRobert Mustacchi mbx->usec_delay = 0; 76575eba5b6SRobert Mustacchi 76675eba5b6SRobert Mustacchi mbx->size = E1000_VFMAILBOX_SIZE; 76775eba5b6SRobert Mustacchi 76875eba5b6SRobert Mustacchi mbx->ops.read = e1000_read_mbx_pf; 76975eba5b6SRobert Mustacchi mbx->ops.write = e1000_write_mbx_pf; 77075eba5b6SRobert Mustacchi mbx->ops.read_posted = e1000_read_posted_mbx; 77175eba5b6SRobert Mustacchi mbx->ops.write_posted = e1000_write_posted_mbx; 77275eba5b6SRobert Mustacchi mbx->ops.check_for_msg = e1000_check_for_msg_pf; 77375eba5b6SRobert Mustacchi mbx->ops.check_for_ack = e1000_check_for_ack_pf; 77475eba5b6SRobert Mustacchi mbx->ops.check_for_rst = e1000_check_for_rst_pf; 77575eba5b6SRobert Mustacchi 77675eba5b6SRobert Mustacchi mbx->stats.msgs_tx = 0; 77775eba5b6SRobert Mustacchi mbx->stats.msgs_rx = 0; 77875eba5b6SRobert Mustacchi mbx->stats.reqs = 0; 77975eba5b6SRobert Mustacchi mbx->stats.acks = 0; 78075eba5b6SRobert Mustacchi mbx->stats.rsts = 0; 78175eba5b6SRobert Mustacchi default: 78275eba5b6SRobert Mustacchi return E1000_SUCCESS; 78375eba5b6SRobert Mustacchi } 78475eba5b6SRobert Mustacchi } 78575eba5b6SRobert Mustacchi 786