338 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2009 - 2018 Intel Corporation. */3 4#include <linux/bitfield.h>5#include "mbx.h"6 7/**8 * e1000_poll_for_msg - Wait for message notification9 * @hw: pointer to the HW structure10 *11 * returns SUCCESS if it successfully received a message notification12 **/13static s32 e1000_poll_for_msg(struct e1000_hw *hw)14{15 struct e1000_mbx_info *mbx = &hw->mbx;16 int countdown = mbx->timeout;17 18 if (!mbx->ops.check_for_msg)19 goto out;20 21 while (countdown && mbx->ops.check_for_msg(hw)) {22 countdown--;23 udelay(mbx->usec_delay);24 }25 26 /* if we failed, all future posted messages fail until reset */27 if (!countdown)28 mbx->timeout = 0;29out:30 return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;31}32 33/**34 * e1000_poll_for_ack - Wait for message acknowledgment35 * @hw: pointer to the HW structure36 *37 * returns SUCCESS if it successfully received a message acknowledgment38 **/39static s32 e1000_poll_for_ack(struct e1000_hw *hw)40{41 struct e1000_mbx_info *mbx = &hw->mbx;42 int countdown = mbx->timeout;43 44 if (!mbx->ops.check_for_ack)45 goto out;46 47 while (countdown && mbx->ops.check_for_ack(hw)) {48 countdown--;49 udelay(mbx->usec_delay);50 }51 52 /* if we failed, all future posted messages fail until reset */53 if (!countdown)54 mbx->timeout = 0;55out:56 return countdown ? E1000_SUCCESS : -E1000_ERR_MBX;57}58 59/**60 * e1000_read_posted_mbx - Wait for message notification and receive message61 * @hw: pointer to the HW structure62 * @msg: The message buffer63 * @size: Length of buffer64 *65 * returns SUCCESS if it successfully received a message notification and66 * copied it into the receive buffer.67 **/68static s32 e1000_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)69{70 struct e1000_mbx_info *mbx = &hw->mbx;71 s32 ret_val = -E1000_ERR_MBX;72 73 if (!mbx->ops.read)74 goto out;75 76 ret_val = e1000_poll_for_msg(hw);77 78 /* if ack received read message, otherwise we timed out */79 if (!ret_val)80 ret_val = mbx->ops.read(hw, msg, size);81out:82 return ret_val;83}84 85/**86 * e1000_write_posted_mbx - Write a message to the mailbox, wait for ack87 * @hw: pointer to the HW structure88 * @msg: The message buffer89 * @size: Length of buffer90 *91 * returns SUCCESS if it successfully copied message into the buffer and92 * received an ack to that message within delay * timeout period93 **/94static s32 e1000_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size)95{96 struct e1000_mbx_info *mbx = &hw->mbx;97 s32 ret_val = -E1000_ERR_MBX;98 99 /* exit if we either can't write or there isn't a defined timeout */100 if (!mbx->ops.write || !mbx->timeout)101 goto out;102 103 /* send msg*/104 ret_val = mbx->ops.write(hw, msg, size);105 106 /* if msg sent wait until we receive an ack */107 if (!ret_val)108 ret_val = e1000_poll_for_ack(hw);109out:110 return ret_val;111}112 113/**114 * e1000_read_v2p_mailbox - read v2p mailbox115 * @hw: pointer to the HW structure116 *117 * This function is used to read the v2p mailbox without losing the read to118 * clear status bits.119 **/120static u32 e1000_read_v2p_mailbox(struct e1000_hw *hw)121{122 u32 v2p_mailbox = er32(V2PMAILBOX(0));123 124 v2p_mailbox |= hw->dev_spec.vf.v2p_mailbox;125 hw->dev_spec.vf.v2p_mailbox |= v2p_mailbox & E1000_V2PMAILBOX_R2C_BITS;126 127 return v2p_mailbox;128}129 130/**131 * e1000_check_for_bit_vf - Determine if a status bit was set132 * @hw: pointer to the HW structure133 * @mask: bitmask for bits to be tested and cleared134 *135 * This function is used to check for the read to clear bits within136 * the V2P mailbox.137 **/138static s32 e1000_check_for_bit_vf(struct e1000_hw *hw, u32 mask)139{140 u32 v2p_mailbox = e1000_read_v2p_mailbox(hw);141 s32 ret_val = -E1000_ERR_MBX;142 143 if (v2p_mailbox & mask)144 ret_val = E1000_SUCCESS;145 146 hw->dev_spec.vf.v2p_mailbox &= ~mask;147 148 return ret_val;149}150 151/**152 * e1000_check_for_msg_vf - checks to see if the PF has sent mail153 * @hw: pointer to the HW structure154 *155 * returns SUCCESS if the PF has set the Status bit or else ERR_MBX156 **/157static s32 e1000_check_for_msg_vf(struct e1000_hw *hw)158{159 s32 ret_val = -E1000_ERR_MBX;160 161 if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFSTS)) {162 ret_val = E1000_SUCCESS;163 hw->mbx.stats.reqs++;164 }165 166 return ret_val;167}168 169/**170 * e1000_check_for_ack_vf - checks to see if the PF has ACK'd171 * @hw: pointer to the HW structure172 *173 * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX174 **/175static s32 e1000_check_for_ack_vf(struct e1000_hw *hw)176{177 s32 ret_val = -E1000_ERR_MBX;178 179 if (!e1000_check_for_bit_vf(hw, E1000_V2PMAILBOX_PFACK)) {180 ret_val = E1000_SUCCESS;181 hw->mbx.stats.acks++;182 }183 184 return ret_val;185}186 187/**188 * e1000_check_for_rst_vf - checks to see if the PF has reset189 * @hw: pointer to the HW structure190 *191 * returns true if the PF has set the reset done bit or else false192 **/193static s32 e1000_check_for_rst_vf(struct e1000_hw *hw)194{195 s32 ret_val = -E1000_ERR_MBX;196 197 if (!e1000_check_for_bit_vf(hw, (E1000_V2PMAILBOX_RSTD |198 E1000_V2PMAILBOX_RSTI))) {199 ret_val = E1000_SUCCESS;200 hw->mbx.stats.rsts++;201 }202 203 return ret_val;204}205 206/**207 * e1000_obtain_mbx_lock_vf - obtain mailbox lock208 * @hw: pointer to the HW structure209 *210 * return SUCCESS if we obtained the mailbox lock211 **/212static s32 e1000_obtain_mbx_lock_vf(struct e1000_hw *hw)213{214 s32 ret_val = -E1000_ERR_MBX;215 int count = 10;216 217 do {218 /* Take ownership of the buffer */219 ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_VFU);220 221 /* reserve mailbox for VF use */222 if (e1000_read_v2p_mailbox(hw) & E1000_V2PMAILBOX_VFU) {223 ret_val = 0;224 break;225 }226 udelay(1000);227 } while (count-- > 0);228 229 return ret_val;230}231 232/**233 * e1000_write_mbx_vf - Write a message to the mailbox234 * @hw: pointer to the HW structure235 * @msg: The message buffer236 * @size: Length of buffer237 *238 * returns SUCCESS if it successfully copied message into the buffer239 **/240static s32 e1000_write_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)241{242 s32 err;243 u16 i;244 245 lockdep_assert_held(&hw->mbx_lock);246 247 /* lock the mailbox to prevent pf/vf race condition */248 err = e1000_obtain_mbx_lock_vf(hw);249 if (err)250 goto out_no_write;251 252 /* flush any ack or msg as we are going to overwrite mailbox */253 e1000_check_for_ack_vf(hw);254 e1000_check_for_msg_vf(hw);255 256 /* copy the caller specified message to the mailbox memory buffer */257 for (i = 0; i < size; i++)258 array_ew32(VMBMEM(0), i, msg[i]);259 260 /* update stats */261 hw->mbx.stats.msgs_tx++;262 263 /* Drop VFU and interrupt the PF to tell it a message has been sent */264 ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_REQ);265 266out_no_write:267 return err;268}269 270/**271 * e1000_read_mbx_vf - Reads a message from the inbox intended for VF272 * @hw: pointer to the HW structure273 * @msg: The message buffer274 * @size: Length of buffer275 *276 * returns SUCCESS if it successfully read message from buffer277 **/278static s32 e1000_read_mbx_vf(struct e1000_hw *hw, u32 *msg, u16 size)279{280 s32 err;281 u16 i;282 283 lockdep_assert_held(&hw->mbx_lock);284 285 /* lock the mailbox to prevent pf/vf race condition */286 err = e1000_obtain_mbx_lock_vf(hw);287 if (err)288 goto out_no_read;289 290 /* copy the message from the mailbox memory buffer */291 for (i = 0; i < size; i++)292 msg[i] = array_er32(VMBMEM(0), i);293 294 /* Acknowledge receipt and release mailbox, then we're done */295 ew32(V2PMAILBOX(0), E1000_V2PMAILBOX_ACK);296 297 /* update stats */298 hw->mbx.stats.msgs_rx++;299 300out_no_read:301 return err;302}303 304/**305 * e1000_init_mbx_params_vf - set initial values for VF mailbox306 * @hw: pointer to the HW structure307 *308 * Initializes the hw->mbx struct to correct values for VF mailbox309 */310s32 e1000_init_mbx_params_vf(struct e1000_hw *hw)311{312 struct e1000_mbx_info *mbx = &hw->mbx;313 314 /* start mailbox as timed out and let the reset_hw call set the timeout315 * value to being communications316 */317 mbx->timeout = 0;318 mbx->usec_delay = E1000_VF_MBX_INIT_DELAY;319 320 mbx->size = E1000_VFMAILBOX_SIZE;321 322 mbx->ops.read = e1000_read_mbx_vf;323 mbx->ops.write = e1000_write_mbx_vf;324 mbx->ops.read_posted = e1000_read_posted_mbx;325 mbx->ops.write_posted = e1000_write_posted_mbx;326 mbx->ops.check_for_msg = e1000_check_for_msg_vf;327 mbx->ops.check_for_ack = e1000_check_for_ack_vf;328 mbx->ops.check_for_rst = e1000_check_for_rst_vf;329 330 mbx->stats.msgs_tx = 0;331 mbx->stats.msgs_rx = 0;332 mbx->stats.reqs = 0;333 mbx->stats.acks = 0;334 mbx->stats.rsts = 0;335 336 return E1000_SUCCESS;337}338