brintos

brintos / linux-shallow public Read only

0
0
Text · 12.8 KiB · a55dd97 Raw
520 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 1999 - 2018 Intel Corporation. */3 4#include "mbx.h"5#include "ixgbevf.h"6 7/**8 *  ixgbevf_poll_for_msg - Wait for message notification9 *  @hw: pointer to the HW structure10 *11 *  returns 0 if it successfully received a message notification12 **/13static s32 ixgbevf_poll_for_msg(struct ixgbe_hw *hw)14{15	struct ixgbe_mbx_info *mbx = &hw->mbx;16	int countdown = mbx->timeout;17 18	if (!countdown || !mbx->ops.check_for_msg)19		return IXGBE_ERR_CONFIG;20 21	while (countdown && mbx->ops.check_for_msg(hw)) {22		countdown--;23		udelay(mbx->udelay);24	}25 26	return countdown ? 0 : IXGBE_ERR_TIMEOUT;27}28 29/**30 *  ixgbevf_poll_for_ack - Wait for message acknowledgment31 *  @hw: pointer to the HW structure32 *33 *  returns 0 if it successfully received a message acknowledgment34 **/35static s32 ixgbevf_poll_for_ack(struct ixgbe_hw *hw)36{37	struct ixgbe_mbx_info *mbx = &hw->mbx;38	int countdown = mbx->timeout;39 40	if (!countdown || !mbx->ops.check_for_ack)41		return IXGBE_ERR_CONFIG;42 43	while (countdown && mbx->ops.check_for_ack(hw)) {44		countdown--;45		udelay(mbx->udelay);46	}47 48	return countdown ? 0 : IXGBE_ERR_TIMEOUT;49}50 51/**52 * ixgbevf_read_mailbox_vf - read VF's mailbox register53 * @hw: pointer to the HW structure54 *55 * This function is used to read the mailbox register dedicated for VF without56 * losing the read to clear status bits.57 **/58static u32 ixgbevf_read_mailbox_vf(struct ixgbe_hw *hw)59{60	u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);61 62	vf_mailbox |= hw->mbx.vf_mailbox;63	hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;64 65	return vf_mailbox;66}67 68/**69 * ixgbevf_clear_msg_vf - clear PF status bit70 * @hw: pointer to the HW structure71 *72 * This function is used to clear PFSTS bit in the VFMAILBOX register73 **/74static void ixgbevf_clear_msg_vf(struct ixgbe_hw *hw)75{76	u32 vf_mailbox = ixgbevf_read_mailbox_vf(hw);77 78	if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {79		hw->mbx.stats.reqs++;80		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;81	}82}83 84/**85 * ixgbevf_clear_ack_vf - clear PF ACK bit86 * @hw: pointer to the HW structure87 *88 * This function is used to clear PFACK bit in the VFMAILBOX register89 **/90static void ixgbevf_clear_ack_vf(struct ixgbe_hw *hw)91{92	u32 vf_mailbox = ixgbevf_read_mailbox_vf(hw);93 94	if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {95		hw->mbx.stats.acks++;96		hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;97	}98}99 100/**101 * ixgbevf_clear_rst_vf - clear PF reset bit102 * @hw: pointer to the HW structure103 *104 * This function is used to clear reset indication and reset done bit in105 * VFMAILBOX register after reset the shared resources and the reset sequence.106 **/107static void ixgbevf_clear_rst_vf(struct ixgbe_hw *hw)108{109	u32 vf_mailbox = ixgbevf_read_mailbox_vf(hw);110 111	if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {112		hw->mbx.stats.rsts++;113		hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |114					IXGBE_VFMAILBOX_RSTD);115	}116}117 118/**119 *  ixgbevf_check_for_bit_vf - Determine if a status bit was set120 *  @hw: pointer to the HW structure121 *  @mask: bitmask for bits to be tested and cleared122 *123 *  This function is used to check for the read to clear bits within124 *  the V2P mailbox.125 **/126static s32 ixgbevf_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)127{128	u32 vf_mailbox = ixgbevf_read_mailbox_vf(hw);129	s32 ret_val = IXGBE_ERR_MBX;130 131	if (vf_mailbox & mask)132		ret_val = 0;133 134	return ret_val;135}136 137/**138 *  ixgbevf_check_for_msg_vf - checks to see if the PF has sent mail139 *  @hw: pointer to the HW structure140 *141 *  returns 0 if the PF has set the Status bit or else ERR_MBX142 **/143static s32 ixgbevf_check_for_msg_vf(struct ixgbe_hw *hw)144{145	s32 ret_val = IXGBE_ERR_MBX;146 147	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {148		ret_val = 0;149		hw->mbx.stats.reqs++;150	}151 152	return ret_val;153}154 155/**156 *  ixgbevf_check_for_ack_vf - checks to see if the PF has ACK'd157 *  @hw: pointer to the HW structure158 *159 *  returns 0 if the PF has set the ACK bit or else ERR_MBX160 **/161static s32 ixgbevf_check_for_ack_vf(struct ixgbe_hw *hw)162{163	s32 ret_val = IXGBE_ERR_MBX;164 165	if (!ixgbevf_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {166		ret_val = 0;167		ixgbevf_clear_ack_vf(hw);168		hw->mbx.stats.acks++;169	}170 171	return ret_val;172}173 174/**175 *  ixgbevf_check_for_rst_vf - checks to see if the PF has reset176 *  @hw: pointer to the HW structure177 *178 *  returns true if the PF has set the reset done bit or else false179 **/180static s32 ixgbevf_check_for_rst_vf(struct ixgbe_hw *hw)181{182	s32 ret_val = IXGBE_ERR_MBX;183 184	if (!ixgbevf_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |185					   IXGBE_VFMAILBOX_RSTI))) {186		ret_val = 0;187		ixgbevf_clear_rst_vf(hw);188		hw->mbx.stats.rsts++;189	}190 191	return ret_val;192}193 194/**195 *  ixgbevf_obtain_mbx_lock_vf - obtain mailbox lock196 *  @hw: pointer to the HW structure197 *198 *  return 0 if we obtained the mailbox lock199 **/200static s32 ixgbevf_obtain_mbx_lock_vf(struct ixgbe_hw *hw)201{202	struct ixgbe_mbx_info *mbx = &hw->mbx;203	s32 ret_val = IXGBE_ERR_CONFIG;204	int countdown = mbx->timeout;205	u32 vf_mailbox;206 207	if (!mbx->timeout)208		return ret_val;209 210	while (countdown--) {211		/* Reserve mailbox for VF use */212		vf_mailbox = ixgbevf_read_mailbox_vf(hw);213		vf_mailbox |= IXGBE_VFMAILBOX_VFU;214		IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);215 216		/* Verify that VF is the owner of the lock */217		if (ixgbevf_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {218			ret_val = 0;219			break;220		}221 222		/* Wait a bit before trying again */223		udelay(mbx->udelay);224	}225 226	if (ret_val)227		ret_val = IXGBE_ERR_TIMEOUT;228 229	return ret_val;230}231 232/**233 * ixgbevf_release_mbx_lock_vf - release mailbox lock234 * @hw: pointer to the HW structure235 **/236static void ixgbevf_release_mbx_lock_vf(struct ixgbe_hw *hw)237{238	u32 vf_mailbox;239 240	/* Return ownership of the buffer */241	vf_mailbox = ixgbevf_read_mailbox_vf(hw);242	vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;243	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);244}245 246/**247 * ixgbevf_release_mbx_lock_vf_legacy - release mailbox lock248 * @hw: pointer to the HW structure249 **/250static void ixgbevf_release_mbx_lock_vf_legacy(struct ixgbe_hw *__always_unused hw)251{252}253 254/**255 *  ixgbevf_write_mbx_vf - Write a message to the mailbox256 *  @hw: pointer to the HW structure257 *  @msg: The message buffer258 *  @size: Length of buffer259 *260 *  returns 0 if it successfully copied message into the buffer261 **/262static s32 ixgbevf_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)263{264	u32 vf_mailbox;265	s32 ret_val;266	u16 i;267 268	/* lock the mailbox to prevent PF/VF race condition */269	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);270	if (ret_val)271		goto out_no_write;272 273	/* flush msg and acks as we are overwriting the message buffer */274	ixgbevf_clear_msg_vf(hw);275	ixgbevf_clear_ack_vf(hw);276 277	/* copy the caller specified message to the mailbox memory buffer */278	for (i = 0; i < size; i++)279		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);280 281	/* update stats */282	hw->mbx.stats.msgs_tx++;283 284	/* interrupt the PF to tell it a message has been sent */285	vf_mailbox = ixgbevf_read_mailbox_vf(hw);286	vf_mailbox |= IXGBE_VFMAILBOX_REQ;287	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);288 289	/* if msg sent wait until we receive an ack */290	ret_val = ixgbevf_poll_for_ack(hw);291 292out_no_write:293	hw->mbx.ops.release(hw);294 295	return ret_val;296}297 298/**299 *  ixgbevf_write_mbx_vf_legacy - Write a message to the mailbox300 *  @hw: pointer to the HW structure301 *  @msg: The message buffer302 *  @size: Length of buffer303 *304 *  returns 0 if it successfully copied message into the buffer305 **/306static s32 ixgbevf_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size)307{308	s32 ret_val;309	u16 i;310 311	/* lock the mailbox to prevent PF/VF race condition */312	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);313	if (ret_val)314		goto out_no_write;315 316	/* flush msg and acks as we are overwriting the message buffer */317	ixgbevf_check_for_msg_vf(hw);318	ixgbevf_clear_msg_vf(hw);319	ixgbevf_check_for_ack_vf(hw);320	ixgbevf_clear_ack_vf(hw);321 322	/* copy the caller specified message to the mailbox memory buffer */323	for (i = 0; i < size; i++)324		IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);325 326	/* update stats */327	hw->mbx.stats.msgs_tx++;328 329	/* Drop VFU and interrupt the PF to tell it a message has been sent */330	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);331 332out_no_write:333	return ret_val;334}335 336/**337 *  ixgbevf_read_mbx_vf - Reads a message from the inbox intended for VF338 *  @hw: pointer to the HW structure339 *  @msg: The message buffer340 *  @size: Length of buffer341 *342 *  returns 0 if it successfully read message from buffer343 **/344static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size)345{346	u32 vf_mailbox;347	s32 ret_val;348	u16 i;349 350	/* check if there is a message from PF */351	ret_val = ixgbevf_check_for_msg_vf(hw);352	if (ret_val)353		return ret_val;354 355	ixgbevf_clear_msg_vf(hw);356 357	/* copy the message from the mailbox memory buffer */358	for (i = 0; i < size; i++)359		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);360 361	/* Acknowledge receipt */362	vf_mailbox = ixgbevf_read_mailbox_vf(hw);363	vf_mailbox |= IXGBE_VFMAILBOX_ACK;364	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);365 366	/* update stats */367	hw->mbx.stats.msgs_rx++;368 369	return ret_val;370}371 372/**373 *  ixgbevf_read_mbx_vf_legacy - Reads a message from the inbox intended for VF374 *  @hw: pointer to the HW structure375 *  @msg: The message buffer376 *  @size: Length of buffer377 *378 *  returns 0 if it successfully read message from buffer379 **/380static s32 ixgbevf_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size)381{382	s32 ret_val = 0;383	u16 i;384 385	/* lock the mailbox to prevent PF/VF race condition */386	ret_val = ixgbevf_obtain_mbx_lock_vf(hw);387	if (ret_val)388		goto out_no_read;389 390	/* copy the message from the mailbox memory buffer */391	for (i = 0; i < size; i++)392		msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);393 394	/* Acknowledge receipt and release mailbox, then we're done */395	IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);396 397	/* update stats */398	hw->mbx.stats.msgs_rx++;399 400out_no_read:401	return ret_val;402}403 404/**405 *  ixgbevf_init_mbx_params_vf - set initial values for VF mailbox406 *  @hw: pointer to the HW structure407 *408 *  Initializes the hw->mbx struct to correct values for VF mailbox409 */410static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw)411{412	struct ixgbe_mbx_info *mbx = &hw->mbx;413 414	/* start mailbox as timed out and let the reset_hw call set the timeout415	 * value to begin communications416	 */417	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;418	mbx->udelay = IXGBE_VF_MBX_INIT_DELAY;419 420	mbx->size = IXGBE_VFMAILBOX_SIZE;421 422	mbx->stats.msgs_tx = 0;423	mbx->stats.msgs_rx = 0;424	mbx->stats.reqs = 0;425	mbx->stats.acks = 0;426	mbx->stats.rsts = 0;427 428	return 0;429}430 431/**432 * ixgbevf_poll_mbx - Wait for message and read it from the mailbox433 * @hw: pointer to the HW structure434 * @msg: The message buffer435 * @size: Length of buffer436 *437 * returns 0 if it successfully read message from buffer438 **/439s32 ixgbevf_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)440{441	struct ixgbe_mbx_info *mbx = &hw->mbx;442	s32 ret_val = IXGBE_ERR_CONFIG;443 444	if (!mbx->ops.read || !mbx->ops.check_for_msg || !mbx->timeout)445		return ret_val;446 447	/* limit read to size of mailbox */448	if (size > mbx->size)449		size = mbx->size;450 451	ret_val = ixgbevf_poll_for_msg(hw);452	/* if ack received read message, otherwise we timed out */453	if (!ret_val)454		ret_val = mbx->ops.read(hw, msg, size);455 456	return ret_val;457}458 459/**460 * ixgbevf_write_mbx - Write a message to the mailbox and wait for ACK461 * @hw: pointer to the HW structure462 * @msg: The message buffer463 * @size: Length of buffer464 *465 * returns 0 if it successfully copied message into the buffer and466 * received an ACK to that message within specified period467 **/468s32 ixgbevf_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size)469{470	struct ixgbe_mbx_info *mbx = &hw->mbx;471	s32 ret_val = IXGBE_ERR_CONFIG;472 473	/**474	 * exit if either we can't write, release475	 * or there is no timeout defined476	 */477	if (!mbx->ops.write || !mbx->ops.check_for_ack || !mbx->ops.release ||478	    !mbx->timeout)479		return ret_val;480 481	if (size > mbx->size)482		ret_val = IXGBE_ERR_PARAM;483	else484		ret_val = mbx->ops.write(hw, msg, size);485 486	return ret_val;487}488 489const struct ixgbe_mbx_operations ixgbevf_mbx_ops = {490	.init_params	= ixgbevf_init_mbx_params_vf,491	.release	= ixgbevf_release_mbx_lock_vf,492	.read		= ixgbevf_read_mbx_vf,493	.write		= ixgbevf_write_mbx_vf,494	.check_for_msg	= ixgbevf_check_for_msg_vf,495	.check_for_ack	= ixgbevf_check_for_ack_vf,496	.check_for_rst	= ixgbevf_check_for_rst_vf,497};498 499const struct ixgbe_mbx_operations ixgbevf_mbx_ops_legacy = {500	.init_params	= ixgbevf_init_mbx_params_vf,501	.release	= ixgbevf_release_mbx_lock_vf_legacy,502	.read		= ixgbevf_read_mbx_vf_legacy,503	.write		= ixgbevf_write_mbx_vf_legacy,504	.check_for_msg	= ixgbevf_check_for_msg_vf,505	.check_for_ack	= ixgbevf_check_for_ack_vf,506	.check_for_rst	= ixgbevf_check_for_rst_vf,507};508 509/* Mailbox operations when running on Hyper-V.510 * On Hyper-V, PF/VF communication is not through the511 * hardware mailbox; this communication is through512 * a software mediated path.513 * Most mail box operations are noop while running on514 * Hyper-V.515 */516const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops = {517	.init_params	= ixgbevf_init_mbx_params_vf,518	.check_for_rst	= ixgbevf_check_for_rst_vf,519};520