18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 1999 - 2018 Intel Corporation. */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/pci.h> 58c2ecf20Sopenharmony_ci#include <linux/delay.h> 68c2ecf20Sopenharmony_ci#include "ixgbe.h" 78c2ecf20Sopenharmony_ci#include "ixgbe_mbx.h" 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/** 108c2ecf20Sopenharmony_ci * ixgbe_read_mbx - Reads a message from the mailbox 118c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 128c2ecf20Sopenharmony_ci * @msg: The message buffer 138c2ecf20Sopenharmony_ci * @size: Length of buffer 148c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to read 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * returns SUCCESS if it successfully read message from buffer 178c2ecf20Sopenharmony_ci **/ 188c2ecf20Sopenharmony_cis32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) 198c2ecf20Sopenharmony_ci{ 208c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci /* limit read to size of mailbox */ 238c2ecf20Sopenharmony_ci if (size > mbx->size) 248c2ecf20Sopenharmony_ci size = mbx->size; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci if (!mbx->ops) 278c2ecf20Sopenharmony_ci return -EIO; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci return mbx->ops->read(hw, msg, size, mbx_id); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/** 338c2ecf20Sopenharmony_ci * ixgbe_write_mbx - Write a message to the mailbox 348c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 358c2ecf20Sopenharmony_ci * @msg: The message buffer 368c2ecf20Sopenharmony_ci * @size: Length of buffer 378c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to write 388c2ecf20Sopenharmony_ci * 398c2ecf20Sopenharmony_ci * returns SUCCESS if it successfully copied message into the buffer 408c2ecf20Sopenharmony_ci **/ 418c2ecf20Sopenharmony_cis32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci if (size > mbx->size) 468c2ecf20Sopenharmony_ci return -EINVAL; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci if (!mbx->ops) 498c2ecf20Sopenharmony_ci return -EIO; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci return mbx->ops->write(hw, msg, size, mbx_id); 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci/** 558c2ecf20Sopenharmony_ci * ixgbe_check_for_msg - checks to see if someone sent us mail 568c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 578c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to check 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * returns SUCCESS if the Status bit was found or else ERR_MBX 608c2ecf20Sopenharmony_ci **/ 618c2ecf20Sopenharmony_cis32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci if (!mbx->ops) 668c2ecf20Sopenharmony_ci return -EIO; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return mbx->ops->check_for_msg(hw, mbx_id); 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/** 728c2ecf20Sopenharmony_ci * ixgbe_check_for_ack - checks to see if someone sent us ACK 738c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 748c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to check 758c2ecf20Sopenharmony_ci * 768c2ecf20Sopenharmony_ci * returns SUCCESS if the Status bit was found or else ERR_MBX 778c2ecf20Sopenharmony_ci **/ 788c2ecf20Sopenharmony_cis32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci if (!mbx->ops) 838c2ecf20Sopenharmony_ci return -EIO; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci return mbx->ops->check_for_ack(hw, mbx_id); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/** 898c2ecf20Sopenharmony_ci * ixgbe_check_for_rst - checks to see if other side has reset 908c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 918c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to check 928c2ecf20Sopenharmony_ci * 938c2ecf20Sopenharmony_ci * returns SUCCESS if the Status bit was found or else ERR_MBX 948c2ecf20Sopenharmony_ci **/ 958c2ecf20Sopenharmony_cis32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci if (!mbx->ops) 1008c2ecf20Sopenharmony_ci return -EIO; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci return mbx->ops->check_for_rst(hw, mbx_id); 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/** 1068c2ecf20Sopenharmony_ci * ixgbe_poll_for_msg - Wait for message notification 1078c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 1088c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to write 1098c2ecf20Sopenharmony_ci * 1108c2ecf20Sopenharmony_ci * returns SUCCESS if it successfully received a message notification 1118c2ecf20Sopenharmony_ci **/ 1128c2ecf20Sopenharmony_cistatic s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) 1138c2ecf20Sopenharmony_ci{ 1148c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 1158c2ecf20Sopenharmony_ci int countdown = mbx->timeout; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci if (!countdown || !mbx->ops) 1188c2ecf20Sopenharmony_ci return -EIO; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci while (mbx->ops->check_for_msg(hw, mbx_id)) { 1218c2ecf20Sopenharmony_ci countdown--; 1228c2ecf20Sopenharmony_ci if (!countdown) 1238c2ecf20Sopenharmony_ci return -EIO; 1248c2ecf20Sopenharmony_ci udelay(mbx->usec_delay); 1258c2ecf20Sopenharmony_ci } 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci return 0; 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/** 1318c2ecf20Sopenharmony_ci * ixgbe_poll_for_ack - Wait for message acknowledgement 1328c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 1338c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to write 1348c2ecf20Sopenharmony_ci * 1358c2ecf20Sopenharmony_ci * returns SUCCESS if it successfully received a message acknowledgement 1368c2ecf20Sopenharmony_ci **/ 1378c2ecf20Sopenharmony_cistatic s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) 1388c2ecf20Sopenharmony_ci{ 1398c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 1408c2ecf20Sopenharmony_ci int countdown = mbx->timeout; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci if (!countdown || !mbx->ops) 1438c2ecf20Sopenharmony_ci return -EIO; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci while (mbx->ops->check_for_ack(hw, mbx_id)) { 1468c2ecf20Sopenharmony_ci countdown--; 1478c2ecf20Sopenharmony_ci if (!countdown) 1488c2ecf20Sopenharmony_ci return -EIO; 1498c2ecf20Sopenharmony_ci udelay(mbx->usec_delay); 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci return 0; 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci/** 1568c2ecf20Sopenharmony_ci * ixgbe_read_posted_mbx - Wait for message notification and receive message 1578c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 1588c2ecf20Sopenharmony_ci * @msg: The message buffer 1598c2ecf20Sopenharmony_ci * @size: Length of buffer 1608c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to write 1618c2ecf20Sopenharmony_ci * 1628c2ecf20Sopenharmony_ci * returns SUCCESS if it successfully received a message notification and 1638c2ecf20Sopenharmony_ci * copied it into the receive buffer. 1648c2ecf20Sopenharmony_ci **/ 1658c2ecf20Sopenharmony_cistatic s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, 1668c2ecf20Sopenharmony_ci u16 mbx_id) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 1698c2ecf20Sopenharmony_ci s32 ret_val; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci if (!mbx->ops) 1728c2ecf20Sopenharmony_ci return -EIO; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci ret_val = ixgbe_poll_for_msg(hw, mbx_id); 1758c2ecf20Sopenharmony_ci if (ret_val) 1768c2ecf20Sopenharmony_ci return ret_val; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci /* if ack received read message */ 1798c2ecf20Sopenharmony_ci return mbx->ops->read(hw, msg, size, mbx_id); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci/** 1838c2ecf20Sopenharmony_ci * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack 1848c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 1858c2ecf20Sopenharmony_ci * @msg: The message buffer 1868c2ecf20Sopenharmony_ci * @size: Length of buffer 1878c2ecf20Sopenharmony_ci * @mbx_id: id of mailbox to write 1888c2ecf20Sopenharmony_ci * 1898c2ecf20Sopenharmony_ci * returns SUCCESS if it successfully copied message into the buffer and 1908c2ecf20Sopenharmony_ci * received an ack to that message within delay * timeout period 1918c2ecf20Sopenharmony_ci **/ 1928c2ecf20Sopenharmony_cistatic s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, 1938c2ecf20Sopenharmony_ci u16 mbx_id) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 1968c2ecf20Sopenharmony_ci s32 ret_val; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci /* exit if either we can't write or there isn't a defined timeout */ 1998c2ecf20Sopenharmony_ci if (!mbx->ops || !mbx->timeout) 2008c2ecf20Sopenharmony_ci return -EIO; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci /* send msg */ 2038c2ecf20Sopenharmony_ci ret_val = mbx->ops->write(hw, msg, size, mbx_id); 2048c2ecf20Sopenharmony_ci if (ret_val) 2058c2ecf20Sopenharmony_ci return ret_val; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci /* if msg sent wait until we receive an ack */ 2088c2ecf20Sopenharmony_ci return ixgbe_poll_for_ack(hw, mbx_id); 2098c2ecf20Sopenharmony_ci} 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_cistatic s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) 2128c2ecf20Sopenharmony_ci{ 2138c2ecf20Sopenharmony_ci u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index)); 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci if (mbvficr & mask) { 2168c2ecf20Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask); 2178c2ecf20Sopenharmony_ci return 0; 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci return -EIO; 2218c2ecf20Sopenharmony_ci} 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci/** 2248c2ecf20Sopenharmony_ci * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail 2258c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 2268c2ecf20Sopenharmony_ci * @vf_number: the VF index 2278c2ecf20Sopenharmony_ci * 2288c2ecf20Sopenharmony_ci * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 2298c2ecf20Sopenharmony_ci **/ 2308c2ecf20Sopenharmony_cistatic s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci s32 index = IXGBE_MBVFICR_INDEX(vf_number); 2338c2ecf20Sopenharmony_ci u32 vf_bit = vf_number % 16; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit, 2368c2ecf20Sopenharmony_ci index)) { 2378c2ecf20Sopenharmony_ci hw->mbx.stats.reqs++; 2388c2ecf20Sopenharmony_ci return 0; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci return -EIO; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci/** 2458c2ecf20Sopenharmony_ci * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed 2468c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 2478c2ecf20Sopenharmony_ci * @vf_number: the VF index 2488c2ecf20Sopenharmony_ci * 2498c2ecf20Sopenharmony_ci * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 2508c2ecf20Sopenharmony_ci **/ 2518c2ecf20Sopenharmony_cistatic s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci s32 index = IXGBE_MBVFICR_INDEX(vf_number); 2548c2ecf20Sopenharmony_ci u32 vf_bit = vf_number % 16; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit, 2578c2ecf20Sopenharmony_ci index)) { 2588c2ecf20Sopenharmony_ci hw->mbx.stats.acks++; 2598c2ecf20Sopenharmony_ci return 0; 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci return -EIO; 2638c2ecf20Sopenharmony_ci} 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci/** 2668c2ecf20Sopenharmony_ci * ixgbe_check_for_rst_pf - checks to see if the VF has reset 2678c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 2688c2ecf20Sopenharmony_ci * @vf_number: the VF index 2698c2ecf20Sopenharmony_ci * 2708c2ecf20Sopenharmony_ci * returns SUCCESS if the VF has set the Status bit or else ERR_MBX 2718c2ecf20Sopenharmony_ci **/ 2728c2ecf20Sopenharmony_cistatic s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci u32 reg_offset = (vf_number < 32) ? 0 : 1; 2758c2ecf20Sopenharmony_ci u32 vf_shift = vf_number % 32; 2768c2ecf20Sopenharmony_ci u32 vflre = 0; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci switch (hw->mac.type) { 2798c2ecf20Sopenharmony_ci case ixgbe_mac_82599EB: 2808c2ecf20Sopenharmony_ci vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset)); 2818c2ecf20Sopenharmony_ci break; 2828c2ecf20Sopenharmony_ci case ixgbe_mac_X540: 2838c2ecf20Sopenharmony_ci case ixgbe_mac_X550: 2848c2ecf20Sopenharmony_ci case ixgbe_mac_X550EM_x: 2858c2ecf20Sopenharmony_ci case ixgbe_mac_x550em_a: 2868c2ecf20Sopenharmony_ci vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); 2878c2ecf20Sopenharmony_ci break; 2888c2ecf20Sopenharmony_ci default: 2898c2ecf20Sopenharmony_ci break; 2908c2ecf20Sopenharmony_ci } 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci if (vflre & BIT(vf_shift)) { 2938c2ecf20Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), BIT(vf_shift)); 2948c2ecf20Sopenharmony_ci hw->mbx.stats.rsts++; 2958c2ecf20Sopenharmony_ci return 0; 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci return -EIO; 2998c2ecf20Sopenharmony_ci} 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci/** 3028c2ecf20Sopenharmony_ci * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock 3038c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 3048c2ecf20Sopenharmony_ci * @vf_number: the VF index 3058c2ecf20Sopenharmony_ci * 3068c2ecf20Sopenharmony_ci * return SUCCESS if we obtained the mailbox lock 3078c2ecf20Sopenharmony_ci **/ 3088c2ecf20Sopenharmony_cistatic s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) 3098c2ecf20Sopenharmony_ci{ 3108c2ecf20Sopenharmony_ci u32 p2v_mailbox; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci /* Take ownership of the buffer */ 3138c2ecf20Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci /* reserve mailbox for vf use */ 3168c2ecf20Sopenharmony_ci p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number)); 3178c2ecf20Sopenharmony_ci if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) 3188c2ecf20Sopenharmony_ci return 0; 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci return -EIO; 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci/** 3248c2ecf20Sopenharmony_ci * ixgbe_write_mbx_pf - Places a message in the mailbox 3258c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 3268c2ecf20Sopenharmony_ci * @msg: The message buffer 3278c2ecf20Sopenharmony_ci * @size: Length of buffer 3288c2ecf20Sopenharmony_ci * @vf_number: the VF index 3298c2ecf20Sopenharmony_ci * 3308c2ecf20Sopenharmony_ci * returns SUCCESS if it successfully copied message into the buffer 3318c2ecf20Sopenharmony_ci **/ 3328c2ecf20Sopenharmony_cistatic s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, 3338c2ecf20Sopenharmony_ci u16 vf_number) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci s32 ret_val; 3368c2ecf20Sopenharmony_ci u16 i; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci /* lock the mailbox to prevent pf/vf race condition */ 3398c2ecf20Sopenharmony_ci ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); 3408c2ecf20Sopenharmony_ci if (ret_val) 3418c2ecf20Sopenharmony_ci return ret_val; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci /* flush msg and acks as we are overwriting the message buffer */ 3448c2ecf20Sopenharmony_ci ixgbe_check_for_msg_pf(hw, vf_number); 3458c2ecf20Sopenharmony_ci ixgbe_check_for_ack_pf(hw, vf_number); 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci /* copy the caller specified message to the mailbox memory buffer */ 3488c2ecf20Sopenharmony_ci for (i = 0; i < size; i++) 3498c2ecf20Sopenharmony_ci IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci /* Interrupt VF to tell it a message has been sent and release buffer*/ 3528c2ecf20Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS); 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci /* update stats */ 3558c2ecf20Sopenharmony_ci hw->mbx.stats.msgs_tx++; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci return 0; 3588c2ecf20Sopenharmony_ci} 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci/** 3618c2ecf20Sopenharmony_ci * ixgbe_read_mbx_pf - Read a message from the mailbox 3628c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 3638c2ecf20Sopenharmony_ci * @msg: The message buffer 3648c2ecf20Sopenharmony_ci * @size: Length of buffer 3658c2ecf20Sopenharmony_ci * @vf_number: the VF index 3668c2ecf20Sopenharmony_ci * 3678c2ecf20Sopenharmony_ci * This function copies a message from the mailbox buffer to the caller's 3688c2ecf20Sopenharmony_ci * memory buffer. The presumption is that the caller knows that there was 3698c2ecf20Sopenharmony_ci * a message due to a VF request so no polling for message is needed. 3708c2ecf20Sopenharmony_ci **/ 3718c2ecf20Sopenharmony_cistatic s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size, 3728c2ecf20Sopenharmony_ci u16 vf_number) 3738c2ecf20Sopenharmony_ci{ 3748c2ecf20Sopenharmony_ci s32 ret_val; 3758c2ecf20Sopenharmony_ci u16 i; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci /* lock the mailbox to prevent pf/vf race condition */ 3788c2ecf20Sopenharmony_ci ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number); 3798c2ecf20Sopenharmony_ci if (ret_val) 3808c2ecf20Sopenharmony_ci return ret_val; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci /* copy the message to the mailbox memory buffer */ 3838c2ecf20Sopenharmony_ci for (i = 0; i < size; i++) 3848c2ecf20Sopenharmony_ci msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i); 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci /* Acknowledge the message and release buffer */ 3878c2ecf20Sopenharmony_ci IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK); 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci /* update stats */ 3908c2ecf20Sopenharmony_ci hw->mbx.stats.msgs_rx++; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci return 0; 3938c2ecf20Sopenharmony_ci} 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI_IOV 3968c2ecf20Sopenharmony_ci/** 3978c2ecf20Sopenharmony_ci * ixgbe_init_mbx_params_pf - set initial values for pf mailbox 3988c2ecf20Sopenharmony_ci * @hw: pointer to the HW structure 3998c2ecf20Sopenharmony_ci * 4008c2ecf20Sopenharmony_ci * Initializes the hw->mbx struct to correct values for pf mailbox 4018c2ecf20Sopenharmony_ci */ 4028c2ecf20Sopenharmony_civoid ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) 4038c2ecf20Sopenharmony_ci{ 4048c2ecf20Sopenharmony_ci struct ixgbe_mbx_info *mbx = &hw->mbx; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci if (hw->mac.type != ixgbe_mac_82599EB && 4078c2ecf20Sopenharmony_ci hw->mac.type != ixgbe_mac_X550 && 4088c2ecf20Sopenharmony_ci hw->mac.type != ixgbe_mac_X550EM_x && 4098c2ecf20Sopenharmony_ci hw->mac.type != ixgbe_mac_x550em_a && 4108c2ecf20Sopenharmony_ci hw->mac.type != ixgbe_mac_X540) 4118c2ecf20Sopenharmony_ci return; 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci mbx->timeout = 0; 4148c2ecf20Sopenharmony_ci mbx->usec_delay = 0; 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci mbx->stats.msgs_tx = 0; 4178c2ecf20Sopenharmony_ci mbx->stats.msgs_rx = 0; 4188c2ecf20Sopenharmony_ci mbx->stats.reqs = 0; 4198c2ecf20Sopenharmony_ci mbx->stats.acks = 0; 4208c2ecf20Sopenharmony_ci mbx->stats.rsts = 0; 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci mbx->size = IXGBE_VFMAILBOX_SIZE; 4238c2ecf20Sopenharmony_ci} 4248c2ecf20Sopenharmony_ci#endif /* CONFIG_PCI_IOV */ 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ciconst struct ixgbe_mbx_operations mbx_ops_generic = { 4278c2ecf20Sopenharmony_ci .read = ixgbe_read_mbx_pf, 4288c2ecf20Sopenharmony_ci .write = ixgbe_write_mbx_pf, 4298c2ecf20Sopenharmony_ci .read_posted = ixgbe_read_posted_mbx, 4308c2ecf20Sopenharmony_ci .write_posted = ixgbe_write_posted_mbx, 4318c2ecf20Sopenharmony_ci .check_for_msg = ixgbe_check_for_msg_pf, 4328c2ecf20Sopenharmony_ci .check_for_ack = ixgbe_check_for_ack_pf, 4338c2ecf20Sopenharmony_ci .check_for_rst = ixgbe_check_for_rst_pf, 4348c2ecf20Sopenharmony_ci}; 4358c2ecf20Sopenharmony_ci 436