brintos

brintos / linux-shallow public Read only

0
0
Text · 8.0 KiB · d15282e Raw
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