Commit 913d14e8 authored by Eran Ben Elisha's avatar Eran Ben Elisha Committed by David S. Miller
Browse files

net/mlx5: Add wrappers for HyperV PCIe operations



Add wrapper functions for HyperV PCIe read / write /
block_invalidate_register operations.  This will be used as an
infrastructure in the downstream patch for software communication.

This will be enabled by default if CONFIG_PCI_HYPERV_INTERFACE is set.

Signed-off-by: default avatarEran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 348dd93e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ mlx5_core-$(CONFIG_MLX5_ESWITCH) += eswitch.o eswitch_offloads.o eswitch_offlo
mlx5_core-$(CONFIG_MLX5_MPFS)      += lib/mpfs.o
mlx5_core-$(CONFIG_VXLAN)          += lib/vxlan.o
mlx5_core-$(CONFIG_PTP_1588_CLOCK) += lib/clock.o
mlx5_core-$(CONFIG_PCI_HYPERV_INTERFACE) += lib/hv.o

#
# Ipoib netdev
+64 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
// Copyright (c) 2018 Mellanox Technologies

#include <linux/hyperv.h>
#include "mlx5_core.h"
#include "lib/hv.h"

static int mlx5_hv_config_common(struct mlx5_core_dev *dev, void *buf, int len,
				 int offset, bool read)
{
	int rc = -EOPNOTSUPP;
	int bytes_returned;
	int block_id;

	if (offset % HV_CONFIG_BLOCK_SIZE_MAX || len % HV_CONFIG_BLOCK_SIZE_MAX)
		return -EINVAL;

	block_id = offset / HV_CONFIG_BLOCK_SIZE_MAX;

	rc = read ?
	     hyperv_read_cfg_blk(dev->pdev, buf,
				 HV_CONFIG_BLOCK_SIZE_MAX, block_id,
				 &bytes_returned) :
	     hyperv_write_cfg_blk(dev->pdev, buf,
				  HV_CONFIG_BLOCK_SIZE_MAX, block_id);

	/* Make sure len bytes were read successfully  */
	if (read)
		rc |= !(len == bytes_returned);

	if (rc) {
		mlx5_core_err(dev, "Failed to %s hv config, err = %d, len = %d, offset = %d\n",
			      read ? "read" : "write", rc, len,
			      offset);
		return rc;
	}

	return 0;
}

int mlx5_hv_read_config(struct mlx5_core_dev *dev, void *buf, int len,
			int offset)
{
	return mlx5_hv_config_common(dev, buf, len, offset, true);
}

int mlx5_hv_write_config(struct mlx5_core_dev *dev, void *buf, int len,
			 int offset)
{
	return mlx5_hv_config_common(dev, buf, len, offset, false);
}

int mlx5_hv_register_invalidate(struct mlx5_core_dev *dev, void *context,
				void (*block_invalidate)(void *context,
							 u64 block_mask))
{
	return hyperv_reg_block_invalidate(dev->pdev, context,
					   block_invalidate);
}

void mlx5_hv_unregister_invalidate(struct mlx5_core_dev *dev)
{
	hyperv_reg_block_invalidate(dev->pdev, NULL, NULL);
}
+22 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2019 Mellanox Technologies. */

#ifndef __LIB_HV_H__
#define __LIB_HV_H__

#if IS_ENABLED(CONFIG_PCI_HYPERV_INTERFACE)

#include <linux/hyperv.h>
#include <linux/mlx5/driver.h>

int mlx5_hv_read_config(struct mlx5_core_dev *dev, void *buf, int len,
			int offset);
int mlx5_hv_write_config(struct mlx5_core_dev *dev, void *buf, int len,
			 int offset);
int mlx5_hv_register_invalidate(struct mlx5_core_dev *dev, void *context,
				void (*block_invalidate)(void *context,
							 u64 block_mask));
void mlx5_hv_unregister_invalidate(struct mlx5_core_dev *dev);
#endif

#endif /* __LIB_HV_H__ */