162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 1999 - 2018 Intel Corporation. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/pci.h> 562306a36Sopenharmony_ci#include <linux/delay.h> 662306a36Sopenharmony_ci#include "ixgbe.h" 762306a36Sopenharmony_ci#include "ixgbe_mbx.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci/** 1062306a36Sopenharmony_ci * ixgbe_read_mbx - Reads a message from the mailbox 1162306a36Sopenharmony_ci * @hw: pointer to the HW structure 1262306a36Sopenharmony_ci * @msg: The message buffer 1362306a36Sopenharmony_ci * @size: Length of buffer 1462306a36Sopenharmony_ci * @mbx_id: id of mailbox to read 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * returns SUCCESS if it successfully read message from buffer 1762306a36Sopenharmony_ci **/ 1862306a36Sopenharmony_cis32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci /* limit read to size of mailbox */ 2362306a36Sopenharmony_ci if (size > mbx->size) 2462306a36Sopenharmony_ci size = mbx->size; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci if (!mbx->ops) 2762306a36Sopenharmony_ci return -EIO; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci return mbx->ops->read(hw, msg, size, mbx_id); 3062306a36Sopenharmony_ci} 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/** 3362306a36Sopenharmony_ci * ixgbe_write_mbx - Write a message to the mailbox 3462306a36Sopenharmony_ci * @hw: pointer to the HW structure 3562306a36Sopenharmony_ci * @msg: The message buffer 3662306a36Sopenharmony_ci * @size: Length of buffer 3762306a36Sopenharmony_ci * @mbx_id: id of mailbox to write 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * returns SUCCESS if it successfully copied message into the buffer 4062306a36Sopenharmony_ci **/ 4162306a36Sopenharmony_cis32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci if (size > mbx->size) 4662306a36Sopenharmony_ci return -EINVAL; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci if (!mbx->ops) 4962306a36Sopenharmony_ci return -EIO; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci return mbx->ops->write(hw, msg, size, mbx_id); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci/** 5562306a36Sopenharmony_ci * ixgbe_check_for_msg - checks to see if someone sent us mail 5662306a36Sopenharmony_ci * @hw: pointer to the HW structure 5762306a36Sopenharmony_ci * @mbx_id: id of mailbox to check 5862306a36Sopenharmony_ci * 5962306a36Sopenharmony_ci * returns SUCCESS if the Status bit was found or else ERR_MBX 6062306a36Sopenharmony_ci **/ 6162306a36Sopenharmony_cis32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci if (!mbx->ops) 6662306a36Sopenharmony_ci return -EIO; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci return mbx->ops->check_for_msg(hw, mbx_id); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/** 7262306a36Sopenharmony_ci * ixgbe_check_for_ack - checks to see if someone sent us ACK 7362306a36Sopenharmony_ci * @hw: pointer to the HW structure 7462306a36Sopenharmony_ci * @mbx_id: id of mailbox to check 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * returns SUCCESS if the Status bit was found or else ERR_MBX 7762306a36Sopenharmony_ci **/ 7862306a36Sopenharmony_cis32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci if (!mbx->ops) 8362306a36Sopenharmony_ci return -EIO; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci return mbx->ops->check_for_ack(hw, mbx_id); 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci/** 8962306a36Sopenharmony_ci * ixgbe_check_for_rst - checks to see if other side has reset 9062306a36Sopenharmony_ci * @hw: pointer to the HW structure 9162306a36Sopenharmony_ci * @mbx_id: id of mailbox to check 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * returns SUCCESS if the Status bit was found or else ERR_MBX 9462306a36Sopenharmony_ci **/ 9562306a36Sopenharmony_cis32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci if (!mbx->ops) 10062306a36Sopenharmony_ci return -EIO; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci return mbx->ops->check_for_rst(hw, mbx_id); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/** 10662306a36Sopenharmony_ci * ixgbe_poll_for_msg - Wait for message notification 10762306a36Sopenharmony_ci * @hw: pointer to the HW structure 10862306a36Sopenharmony_ci * @mbx_id: id of mailbox to write 10962306a36Sopenharmony_ci * 11062306a36Sopenharmony_ci * returns SUCCESS if it successfully received a message notification 11162306a36Sopenharmony_ci **/ 11262306a36Sopenharmony_cistatic s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 11562306a36Sopenharmony_ci int countdown = mbx->timeout; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci if (!countdown || !mbx->ops) 11862306a36Sopenharmony_ci return -EIO; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci while (mbx->ops->check_for_msg(hw, mbx_id)) { 12162306a36Sopenharmony_ci countdown--; 12262306a36Sopenharmony_ci if (!countdown) 12362306a36Sopenharmony_ci return -EIO; 12462306a36Sopenharmony_ci udelay(mbx->usec_delay); 12562306a36Sopenharmony_ci } 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci return 0; 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/** 13162306a36Sopenharmony_ci * ixgbe_poll_for_ack - Wait for message acknowledgement 13262306a36Sopenharmony_ci * @hw: pointer to the HW structure 13362306a36Sopenharmony_ci * @mbx_id: id of mailbox to write 13462306a36Sopenharmony_ci * 13562306a36Sopenharmony_ci * returns SUCCESS if it successfully received a message acknowledgement 13662306a36Sopenharmony_ci **/ 13762306a36Sopenharmony_cistatic s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 14062306a36Sopenharmony_ci int countdown = mbx->timeout; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci if (!countdown || !mbx->ops) 14362306a36Sopenharmony_ci return -EIO; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci while (mbx->ops->check_for_ack(hw, mbx_id)) { 14662306a36Sopenharmony_ci countdown--; 14762306a36Sopenharmony_ci if (!countdown) 14862306a36Sopenharmony_ci return -EIO; 14962306a36Sopenharmony_ci udelay(mbx->usec_delay); 15062306a36Sopenharmony_ci } 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci return 0; 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci/** 15662306a36Sopenharmony_ci * ixgbe_read_posted_mbx - Wait for message notification and receive message 15762306a36Sopenharmony_ci * @hw: pointer to the HW structure 15862306a36Sopenharmony_ci * @msg: The message buffer 15962306a36Sopenharmony_ci * @size: Length of buffer 16062306a36Sopenharmony_ci * @mbx_id: id of mailbox to write 16162306a36Sopenharmony_ci * 16262306a36Sopenharmony_ci * returns SUCCESS if it successfully received a message notification and 16362306a36Sopenharmony_ci * copied it into the receive buffer. 16462306a36Sopenharmony_ci **/ 16562306a36Sopenharmony_cistatic s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, 16662306a36Sopenharmony_ci u16 mbx_id) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 16962306a36Sopenharmony_ci s32 ret_val; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci if (!mbx->ops) 17262306a36Sopenharmony_ci return -EIO; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci ret_val = ixgbe_poll_for_msg(hw, mbx_id); 17562306a36Sopenharmony_ci if (ret_val) 17662306a36Sopenharmony_ci return ret_val; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci /* if ack received read message */ 17962306a36Sopenharmony_ci return mbx->ops->read(hw, msg, size, mbx_id); 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/** 18362306a36Sopenharmony_ci * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack 18462306a36Sopenharmony_ci * @hw: pointer to the HW structure 18562306a36Sopenharmony_ci * @msg: The message buffer 18662306a36Sopenharmony_ci * @size: Length of buffer 18762306a36Sopenharmony_ci * @mbx_id: id of mailbox to write 18862306a36Sopenharmony_ci * 18962306a36Sopenharmony_ci * returns SUCCESS if it successfully copied message into the buffer and 19062306a36Sopenharmony_ci * received an ack to that message within delay * timeout period 19162306a36Sopenharmony_ci **/ 19262306a36Sopenharmony_cistatic s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, 19362306a36Sopenharmony_ci u16 mbx_id) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 19662306a36Sopenharmony_ci s32 ret_val; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci /* exit if either we can't write or there isn't a defined timeout */ 19962306a36Sopenharmony_ci if (!mbx->ops || !mbx->timeout) 20062306a36Sopenharmony_ci return -EIO; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci /* send msg */ 20362306a36Sopenharmony_ci ret_val = mbx->ops->write(hw, msg, size, mbx_id); 20462306a36Sopenharmony_ci if (ret_val) 20562306a36Sopenharmony_ci return ret_val; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci /* if msg sent wait until we receive an ack */ 20862306a36Sopenharmony_ci return ixgbe_poll_for_ack(hw, mbx_id); 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cistatic s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index)); 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci if (mbvficr & mask) { 21662306a36Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask); 21762306a36Sopenharmony_ci return 0; 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci return -EIO; 22162306a36Sopenharmony_ci} 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci/** 22462306a36Sopenharmony_ci * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail 22562306a36Sopenharmony_ci * @hw: pointer to the HW structure 22662306a36Sopenharmony_ci * @vf_number: the VF index 22762306a36Sopenharmony_ci * 22862306a36Sopenharmony_ci * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 22962306a36Sopenharmony_ci **/ 23062306a36Sopenharmony_cistatic s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci s32 index = IXGBE_MBVFICR_INDEX(vf_number); 23362306a36Sopenharmony_ci u32 vf_bit = vf_number % 16; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit, 23662306a36Sopenharmony_ci index)) { 23762306a36Sopenharmony_ci hw->mbx.stats.reqs++; 23862306a36Sopenharmony_ci return 0; 23962306a36Sopenharmony_ci } 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci return -EIO; 24262306a36Sopenharmony_ci} 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci/** 24562306a36Sopenharmony_ci * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed 24662306a36Sopenharmony_ci * @hw: pointer to the HW structure 24762306a36Sopenharmony_ci * @vf_number: the VF index 24862306a36Sopenharmony_ci * 24962306a36Sopenharmony_ci * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 25062306a36Sopenharmony_ci **/ 25162306a36Sopenharmony_cistatic s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) 25262306a36Sopenharmony_ci{ 25362306a36Sopenharmony_ci s32 index = IXGBE_MBVFICR_INDEX(vf_number); 25462306a36Sopenharmony_ci u32 vf_bit = vf_number % 16; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit, 25762306a36Sopenharmony_ci index)) { 25862306a36Sopenharmony_ci hw->mbx.stats.acks++; 25962306a36Sopenharmony_ci return 0; 26062306a36Sopenharmony_ci } 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci return -EIO; 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci/** 26662306a36Sopenharmony_ci * ixgbe_check_for_rst_pf - checks to see if the VF has reset 26762306a36Sopenharmony_ci * @hw: pointer to the HW structure 26862306a36Sopenharmony_ci * @vf_number: the VF index 26962306a36Sopenharmony_ci * 27062306a36Sopenharmony_ci * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 27162306a36Sopenharmony_ci **/ 27262306a36Sopenharmony_cistatic s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) 27362306a36Sopenharmony_ci{ 27462306a36Sopenharmony_ci u32 reg_offset = (vf_number < 32) ? 0 : 1; 27562306a36Sopenharmony_ci u32 vf_shift = vf_number % 32; 27662306a36Sopenharmony_ci u32 vflre = 0; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci switch (hw->mac.type) { 27962306a36Sopenharmony_ci case ixgbe_mac_82599EB: 28062306a36Sopenharmony_ci vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); 28162306a36Sopenharmony_ci break; 28262306a36Sopenharmony_ci case ixgbe_mac_X540: 28362306a36Sopenharmony_ci case ixgbe_mac_X550: 28462306a36Sopenharmony_ci case ixgbe_mac_X550EM_x: 28562306a36Sopenharmony_ci case ixgbe_mac_x550em_a: 28662306a36Sopenharmony_ci vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); 28762306a36Sopenharmony_ci break; 28862306a36Sopenharmony_ci default: 28962306a36Sopenharmony_ci break; 29062306a36Sopenharmony_ci } 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci if (vflre & BIT(vf_shift)) { 29362306a36Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), BIT(vf_shift)); 29462306a36Sopenharmony_ci hw->mbx.stats.rsts++; 29562306a36Sopenharmony_ci return 0; 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci return -EIO; 29962306a36Sopenharmony_ci} 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci/** 30262306a36Sopenharmony_ci * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock 30362306a36Sopenharmony_ci * @hw: pointer to the HW structure 30462306a36Sopenharmony_ci * @vf_number: the VF index 30562306a36Sopenharmony_ci * 30662306a36Sopenharmony_ci * return SUCCESS if we obtained the mailbox lock 30762306a36Sopenharmony_ci **/ 30862306a36Sopenharmony_cistatic s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) 30962306a36Sopenharmony_ci{ 31062306a36Sopenharmony_ci u32 p2v_mailbox; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci /* Take ownership of the buffer */ 31362306a36Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* reserve mailbox for vf use */ 31662306a36Sopenharmony_ci p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number)); 31762306a36Sopenharmony_ci if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) 31862306a36Sopenharmony_ci return 0; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci return -EIO; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci/** 32462306a36Sopenharmony_ci * ixgbe_write_mbx_pf - Places a message in the mailbox 32562306a36Sopenharmony_ci * @hw: pointer to the HW structure 32662306a36Sopenharmony_ci * @msg: The message buffer 32762306a36Sopenharmony_ci * @size: Length of buffer 32862306a36Sopenharmony_ci * @vf_number: the VF index 32962306a36Sopenharmony_ci * 33062306a36Sopenharmony_ci * returns SUCCESS if it successfully copied message into the buffer 33162306a36Sopenharmony_ci **/ 33262306a36Sopenharmony_cistatic s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, 33362306a36Sopenharmony_ci u16 vf_number) 33462306a36Sopenharmony_ci{ 33562306a36Sopenharmony_ci s32 ret_val; 33662306a36Sopenharmony_ci u16 i; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci /* lock the mailbox to prevent pf/vf race condition */ 33962306a36Sopenharmony_ci ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); 34062306a36Sopenharmony_ci if (ret_val) 34162306a36Sopenharmony_ci return ret_val; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci /* flush msg and acks as we are overwriting the message buffer */ 34462306a36Sopenharmony_ci ixgbe_check_for_msg_pf(hw, vf_number); 34562306a36Sopenharmony_ci ixgbe_check_for_ack_pf(hw, vf_number); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci /* copy the caller specified message to the mailbox memory buffer */ 34862306a36Sopenharmony_ci for (i = 0; i < size; i++) 34962306a36Sopenharmony_ci IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]); 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci /* Interrupt VF to tell it a message has been sent and release buffer*/ 35262306a36Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS); 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci /* update stats */ 35562306a36Sopenharmony_ci hw->mbx.stats.msgs_tx++; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci return 0; 35862306a36Sopenharmony_ci} 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci/** 36162306a36Sopenharmony_ci * ixgbe_read_mbx_pf - Read a message from the mailbox 36262306a36Sopenharmony_ci * @hw: pointer to the HW structure 36362306a36Sopenharmony_ci * @msg: The message buffer 36462306a36Sopenharmony_ci * @size: Length of buffer 36562306a36Sopenharmony_ci * @vf_number: the VF index 36662306a36Sopenharmony_ci * 36762306a36Sopenharmony_ci * This function copies a message from the mailbox buffer to the caller's 36862306a36Sopenharmony_ci * memory buffer. The presumption is that the caller knows that there was 36962306a36Sopenharmony_ci * a message due to a VF request so no polling for message is needed. 37062306a36Sopenharmony_ci **/ 37162306a36Sopenharmony_cistatic s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, 37262306a36Sopenharmony_ci u16 vf_number) 37362306a36Sopenharmony_ci{ 37462306a36Sopenharmony_ci s32 ret_val; 37562306a36Sopenharmony_ci u16 i; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci /* lock the mailbox to prevent pf/vf race condition */ 37862306a36Sopenharmony_ci ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); 37962306a36Sopenharmony_ci if (ret_val) 38062306a36Sopenharmony_ci return ret_val; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci /* copy the message to the mailbox memory buffer */ 38362306a36Sopenharmony_ci for (i = 0; i < size; i++) 38462306a36Sopenharmony_ci msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i); 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci /* Acknowledge the message and release buffer */ 38762306a36Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK); 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci /* update stats */ 39062306a36Sopenharmony_ci hw->mbx.stats.msgs_rx++; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci return 0; 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci#ifdef CONFIG_PCI_IOV 39662306a36Sopenharmony_ci/** 39762306a36Sopenharmony_ci * ixgbe_init_mbx_params_pf - set initial values for pf mailbox 39862306a36Sopenharmony_ci * @hw: pointer to the HW structure 39962306a36Sopenharmony_ci * 40062306a36Sopenharmony_ci * Initializes the hw->mbx struct to correct values for pf mailbox 40162306a36Sopenharmony_ci */ 40262306a36Sopenharmony_civoid ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci if (hw->mac.type != ixgbe_mac_82599EB && 40762306a36Sopenharmony_ci hw->mac.type != ixgbe_mac_X550 && 40862306a36Sopenharmony_ci hw->mac.type != ixgbe_mac_X550EM_x && 40962306a36Sopenharmony_ci hw->mac.type != ixgbe_mac_x550em_a && 41062306a36Sopenharmony_ci hw->mac.type != ixgbe_mac_X540) 41162306a36Sopenharmony_ci return; 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci mbx->timeout = 0; 41462306a36Sopenharmony_ci mbx->usec_delay = 0; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci mbx->stats.msgs_tx = 0; 41762306a36Sopenharmony_ci mbx->stats.msgs_rx = 0; 41862306a36Sopenharmony_ci mbx->stats.reqs = 0; 41962306a36Sopenharmony_ci mbx->stats.acks = 0; 42062306a36Sopenharmony_ci mbx->stats.rsts = 0; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci mbx->size = IXGBE_VFMAILBOX_SIZE; 42362306a36Sopenharmony_ci} 42462306a36Sopenharmony_ci#endif /* CONFIG_PCI_IOV */ 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ciconst struct ixgbe_mbx_operations mbx_ops_generic = { 42762306a36Sopenharmony_ci .read = ixgbe_read_mbx_pf, 42862306a36Sopenharmony_ci .write = ixgbe_write_mbx_pf, 42962306a36Sopenharmony_ci .read_posted = ixgbe_read_posted_mbx, 43062306a36Sopenharmony_ci .write_posted = ixgbe_write_posted_mbx, 43162306a36Sopenharmony_ci .check_for_msg = ixgbe_check_for_msg_pf, 43262306a36Sopenharmony_ci .check_for_ack = ixgbe_check_for_ack_pf, 43362306a36Sopenharmony_ci .check_for_rst = ixgbe_check_for_rst_pf, 43462306a36Sopenharmony_ci}; 43562306a36Sopenharmony_ci 436