On 8/14/19 12:08 PM, Haiyang Zhang wrote: > From: Eran Ben Elisha <eranbe@xxxxxxxxxxxx> > > 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_MINI is set. > > Signed-off-by: Eran Ben Elisha <eranbe@xxxxxxxxxxxx> > Signed-off-by: Saeed Mahameed <saeedm@xxxxxxxxxxxx> > --- > drivers/net/ethernet/mellanox/mlx5/core/Makefile | 1 + > drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c | 64 ++++++++++++++++++++++++ > drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h | 22 ++++++++ > 3 files changed, 87 insertions(+) > create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c > create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h > > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile > index 8b7edaa..a8950b1 100644 > --- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile > +++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile > @@ -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_MINI) += lib/hv.o > > # > # Ipoib netdev > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c > new file mode 100644 > index 0000000..cf08d02 > --- /dev/null > +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c > @@ -0,0 +1,64 @@ > +// 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; > +} This seems out of place why not expose this function as part of hyperv and mlx5 will just pass the pdev. > + > +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); > +} > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h > new file mode 100644 > index 0000000..7f69771 > --- /dev/null > +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv.h > @@ -0,0 +1,22 @@ > +/* 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_MINI) > + > +#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__ */ > Mark