lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <7ff67363-c309-4490-aff9-d8eb09556b70@intel.com>
Date: Wed, 5 Jun 2024 09:42:06 +0200
From: Wojciech Drewek <wojciech.drewek@...el.com>
To: Mengyuan Lou <mengyuanlou@...-swift.com>, <netdev@...r.kernel.org>
CC: <jiawenwu@...stnetic.com>, <duanqiangwen@...-swift.com>
Subject: Re: [PATCH net-next v4 2/6] net: libwx: Add sriov api for wangxun
 nics



On 04.06.2024 17:57, Mengyuan Lou wrote:
> Implement sriov_configure interface for wangxun nics in libwx.

you could elaborate a bit more

> 
> Signed-off-by: Mengyuan Lou <mengyuanlou@...-swift.com>
> ---
>  drivers/net/ethernet/wangxun/libwx/Makefile   |   2 +-
>  drivers/net/ethernet/wangxun/libwx/wx_mbx.h   |   4 +
>  drivers/net/ethernet/wangxun/libwx/wx_sriov.c | 221 ++++++++++++++++++
>  drivers/net/ethernet/wangxun/libwx/wx_sriov.h |  10 +
>  drivers/net/ethernet/wangxun/libwx/wx_type.h  |  38 +++
>  5 files changed, 274 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/ethernet/wangxun/libwx/wx_sriov.c
>  create mode 100644 drivers/net/ethernet/wangxun/libwx/wx_sriov.h
> 
> diff --git a/drivers/net/ethernet/wangxun/libwx/Makefile b/drivers/net/ethernet/wangxun/libwx/Makefile
> index 913a978c9032..5b996d973d29 100644
> --- a/drivers/net/ethernet/wangxun/libwx/Makefile
> +++ b/drivers/net/ethernet/wangxun/libwx/Makefile
> @@ -4,4 +4,4 @@
>  
>  obj-$(CONFIG_LIBWX) += libwx.o
>  
> -libwx-objs := wx_hw.o wx_lib.o wx_ethtool.o wx_mbx.o
> +libwx-objs := wx_hw.o wx_lib.o wx_ethtool.o wx_mbx.o wx_sriov.o
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_mbx.h b/drivers/net/ethernet/wangxun/libwx/wx_mbx.h
> index 1579096fb6ad..3c70654a8b14 100644
> --- a/drivers/net/ethernet/wangxun/libwx/wx_mbx.h
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_mbx.h
> @@ -23,6 +23,10 @@
>  
>  #define WX_VT_MSGINFO_MASK    GENMASK(23, 16)
>  
> +enum wxvf_xcast_modes {
> +	WXVF_XCAST_MODE_NONE = 0,
> +};
> +
>  int wx_write_mbx_pf(struct wx *wx, u32 *msg, u16 size, u16 vf);
>  int wx_read_mbx_pf(struct wx *wx, u32 *msg, u16 size, u16 vf);
>  int wx_check_for_rst_pf(struct wx *wx, u16 mbx_id);
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_sriov.c b/drivers/net/ethernet/wangxun/libwx/wx_sriov.c
> new file mode 100644
> index 000000000000..032b75f23460
> --- /dev/null
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_sriov.c
> @@ -0,0 +1,221 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */
> +
> +#include <linux/etherdevice.h>
> +#include <linux/pci.h>
> +
> +#include "wx_type.h"
> +#include "wx_mbx.h"
> +#include "wx_sriov.h"
> +
> +static void wx_vf_configuration(struct pci_dev *pdev, int event_mask)
> +{
> +	unsigned int vfn = (event_mask & GENMASK(5, 0));
> +	struct wx *wx = pci_get_drvdata(pdev);
> +
> +	bool enable = ((event_mask & BIT(31)) != 0);
> +
> +	if (enable)
> +		eth_zero_addr(wx->vfinfo[vfn].vf_mac_addr);
> +}
> +
> +static void wx_alloc_vf_macvlans(struct wx *wx, u8 num_vfs)
> +{
> +	struct vf_macvlans *mv_list;
> +	int num_vf_macvlans, i;
> +
> +	/* Initialize list of VF macvlans */
> +	INIT_LIST_HEAD(&wx->vf_mvs.l);
> +
> +	num_vf_macvlans = wx->mac.num_rar_entries -
> +			  (WX_MAX_PF_MACVLANS + 1 + num_vfs);
> +	if (!num_vf_macvlans)
> +		return;
> +
> +	mv_list = kcalloc(num_vf_macvlans, sizeof(struct vf_macvlans),
> +			  GFP_KERNEL);
> +	if (mv_list) {
> +		for (i = 0; i < num_vf_macvlans; i++) {
> +			mv_list[i].vf = -1;
> +			mv_list[i].free = true;
> +			list_add(&mv_list[i].l, &wx->vf_mvs.l);
> +		}
> +		wx->mv_list = mv_list;
> +	}
> +}
> +
> +static int __wx_enable_sriov(struct wx *wx, u8 num_vfs)
> +{
> +	u32 value = 0;
> +	int i;
> +
> +	set_bit(WX_FLAG_SRIOV_ENABLED, wx->flags);
> +	wx_err(wx, "SR-IOV enabled with %d VFs\n", num_vfs);
> +
> +	/* Enable VMDq flag so device will be set in VM mode */
> +	set_bit(WX_FLAG_VMDQ_ENABLED, wx->flags);
> +	if (!wx->ring_feature[RING_F_VMDQ].limit)
> +		wx->ring_feature[RING_F_VMDQ].limit = 1;
> +	wx->ring_feature[RING_F_VMDQ].offset = num_vfs;
> +
> +	wx_alloc_vf_macvlans(wx, num_vfs);
> +	/* Initialize default switching mode VEB */
> +	wr32m(wx, WX_PSR_CTL, WX_PSR_CTL_SW_EN, WX_PSR_CTL_SW_EN);
> +
> +	/* If call to enable VFs succeeded then allocate memory
> +	 * for per VF control structures.
> +	 */
> +	wx->vfinfo = kcalloc(num_vfs, sizeof(struct vf_data_storage), GFP_KERNEL);
> +	if (!wx->vfinfo)
> +		return -ENOMEM;
> +
> +	/* enable spoof checking for all VFs */
> +	for (i = 0; i < num_vfs; i++) {
> +		/* enable spoof checking for all VFs */
> +		wx->vfinfo[i].spoofchk_enabled = true;
> +		wx->vfinfo[i].link_enable = true;
> +		/* Untrust all VFs */
> +		wx->vfinfo[i].trusted = false;
> +		/* set the default xcast mode */
> +		wx->vfinfo[i].xcast_mode = WXVF_XCAST_MODE_NONE;
> +	}
> +
> +	if (wx->mac.type == wx_mac_sp) {
> +		if (num_vfs < 32)
> +			value = WX_CFG_PORT_CTL_NUM_VT_32;
> +		else
> +			value = WX_CFG_PORT_CTL_NUM_VT_64;
> +	} else {
> +		value = WX_CFG_PORT_CTL_NUM_VT_8;
> +	}
> +	wr32m(wx, WX_CFG_PORT_CTL,
> +	      WX_CFG_PORT_CTL_NUM_VT_MASK,
> +	      value);
> +
> +	return 0;
> +}
> +
> +static void wx_sriov_reinit(struct wx *wx)
> +{
> +	rtnl_lock();
> +	wx->setup_tc(wx->netdev, netdev_get_num_tc(wx->netdev));
> +	rtnl_unlock();
> +}
> +
> +int wx_disable_sriov(struct wx *wx)
> +{
> +	/* If our VFs are assigned we cannot shut down SR-IOV
> +	 * without causing issues, so just leave the hardware
> +	 * available but disabled
> +	 */
> +	if (pci_vfs_assigned(wx->pdev)) {
> +		wx_err(wx, "Unloading driver while VFs are assigned.\n");
> +		return -EPERM;
> +	}
> +	/* disable iov and allow time for transactions to clear */
> +	pci_disable_sriov(wx->pdev);
> +
> +	/* set num VFs to 0 to prevent access to vfinfo */
> +	wx->num_vfs = 0;
> +
> +	/* free VF control structures */
> +	kfree(wx->vfinfo);
> +	wx->vfinfo = NULL;
> +
> +	/* free macvlan list */
> +	kfree(wx->mv_list);
> +	wx->mv_list = NULL;
> +
> +	/* set default pool back to 0 */
> +	wr32m(wx, WX_PSR_VM_CTL, WX_PSR_VM_CTL_POOL_MASK, 0);
> +	wx->ring_feature[RING_F_VMDQ].offset = 0;
> +
> +	clear_bit(WX_FLAG_SRIOV_ENABLED, wx->flags);
> +	/* Disable VMDq flag so device will be set in VM mode */
> +	if (wx->ring_feature[RING_F_VMDQ].limit == 1)
> +		clear_bit(WX_FLAG_VMDQ_ENABLED, wx->flags);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(wx_disable_sriov);
> +
> +static int wx_pci_sriov_enable(struct pci_dev *dev,
> +			       int num_vfs)
> +{
> +	struct wx *wx = pci_get_drvdata(dev);
> +	int err = 0, i;
> +
> +	err = __wx_enable_sriov(wx, num_vfs);
> +	if (err)
> +		goto err_out;
> +
> +	wx->num_vfs = num_vfs;
> +	for (i = 0; i < wx->num_vfs; i++)
> +		wx_vf_configuration(dev, (i | BIT(31)));
> +
> +	/* reset before enabling SRIOV to avoid mailbox issues */
> +	wx_sriov_reinit(wx);
> +
> +	err = pci_enable_sriov(dev, num_vfs);
> +	if (err) {

Shouldn't you unroll previous configuration if pci_enable_sriov fails?

> +		wx_err(wx, "Failed to enable PCI sriov: %d\n", err);
> +		goto err_out;
> +	}
> +
> +	return num_vfs;
> +err_out:
> +	return err;
> +}
> +
> +static int wx_pci_sriov_disable(struct pci_dev *dev)
> +{
> +	struct wx *wx = pci_get_drvdata(dev);
> +	int err;
> +
> +	err = wx_disable_sriov(wx);
> +
> +	/* reset before enabling SRIOV to avoid mailbox issues */
> +	if (!err)
> +		wx_sriov_reinit(wx);
> +
> +	return err;
> +}
> +
> +static int wx_check_sriov_allowed(struct wx *wx, int num_vfs)
> +{
> +	u16 max_vfs;
> +
> +	max_vfs = (wx->mac.type == wx_mac_sp) ? 63 : 7;
> +
> +	if (num_vfs > max_vfs)
> +		return -EPERM;
> +
> +	return 0;
> +}
> +
> +int wx_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
> +{
> +	struct wx *wx = pci_get_drvdata(pdev);
> +	int err;
> +
> +	err = wx_check_sriov_allowed(wx, num_vfs);
> +	if (err)
> +		return err;
> +
> +	if (!num_vfs) {
> +		if (!pci_vfs_assigned(pdev)) {
> +			wx_pci_sriov_disable(pdev);
> +			return 0;
> +		}
> +
> +		wx_err(wx, "can't free VFs because some are assigned to VMs.\n");
> +		return -EBUSY;
> +	}
> +
> +	err = wx_pci_sriov_enable(pdev, num_vfs);
> +	if (err)
> +		return err;
> +
> +	return num_vfs;
> +}
> +EXPORT_SYMBOL(wx_pci_sriov_configure);
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_sriov.h b/drivers/net/ethernet/wangxun/libwx/wx_sriov.h
> new file mode 100644
> index 000000000000..17b547ae8862
> --- /dev/null
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_sriov.h
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (c) 2015 - 2024 Beijing WangXun Technology Co., Ltd. */
> +
> +#ifndef _WX_SRIOV_H_
> +#define _WX_SRIOV_H_
> +
> +int wx_disable_sriov(struct wx *wx);
> +int wx_pci_sriov_configure(struct pci_dev *pdev, int num_vfs);
> +
> +#endif /* _WX_SRIOV_H_ */
> diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
> index caa2f4157834..7dad022e01e9 100644
> --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
> +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
> @@ -18,6 +18,7 @@
>  /* MSI-X capability fields masks */
>  #define WX_PCIE_MSIX_TBL_SZ_MASK                0x7FF
>  #define WX_PCI_LINK_STATUS                      0xB2
> +#define WX_MAX_PF_MACVLANS                      15
>  
>  /**************** Global Registers ****************************/
>  /* chip control Registers */
> @@ -88,6 +89,9 @@
>  #define WX_CFG_TAG_TPID(_i)          (0x14430 + ((_i) * 4))
>  #define WX_CFG_PORT_CTL_NUM_VT_MASK  GENMASK(13, 12) /* number of TVs */
>  
> +#define WX_CFG_PORT_CTL_NUM_VT_8     FIELD_PREP(GENMASK(13, 12), 1)
> +#define WX_CFG_PORT_CTL_NUM_VT_32    FIELD_PREP(GENMASK(13, 12), 2)
> +#define WX_CFG_PORT_CTL_NUM_VT_64    FIELD_PREP(GENMASK(13, 12), 3)
>  
>  /* GPIO Registers */
>  #define WX_GPIO_DR                   0x14800
> @@ -161,6 +165,7 @@
>  /******************************* PSR Registers *******************************/
>  /* psr control */
>  #define WX_PSR_CTL                   0x15000
> +#define WX_PSR_VM_CTL                0x151B0
>  /* Header split receive */
>  #define WX_PSR_CTL_SW_EN             BIT(18)
>  #define WX_PSR_CTL_RSC_ACK           BIT(17)
> @@ -181,6 +186,7 @@
>  /* mcasst/ucast overflow tbl */
>  #define WX_PSR_MC_TBL(_i)            (0x15200  + ((_i) * 4))
>  #define WX_PSR_UC_TBL(_i)            (0x15400 + ((_i) * 4))
> +#define WX_PSR_VM_CTL_POOL_MASK      GENMASK(12, 7)
>  
>  /* VM L2 contorl */
>  #define WX_PSR_VM_L2CTL(_i)          (0x15600 + ((_i) * 4))
> @@ -943,6 +949,7 @@ struct wx_ring_feature {
>  enum wx_ring_f_enum {
>  	RING_F_NONE = 0,
>  	RING_F_RSS,
> +	RING_F_VMDQ,
>  	RING_F_ARRAY_SIZE  /* must be last in enum set */
>  };
>  
> @@ -990,9 +997,34 @@ enum wx_state {
>  	WX_STATE_RESETTING,
>  	WX_STATE_NBITS,		/* must be last */
>  };
> +
> +struct vf_data_storage {
> +	struct pci_dev *vfdev;
> +	unsigned char vf_mac_addr[ETH_ALEN];
> +	bool spoofchk_enabled;
> +	bool link_enable;
> +	bool trusted;
> +	int xcast_mode;
> +};
> +
> +struct vf_macvlans {
> +	struct list_head l;

l is too short IMO

> +	int vf;
> +	bool free;
> +	bool is_macvlan;
> +	u8 vf_macvlan[ETH_ALEN];
> +};
> +
> +enum wx_pf_flags {
> +	WX_FLAG_VMDQ_ENABLED,
> +	WX_FLAG_SRIOV_ENABLED,
> +	WX_PF_FLAGS_NBITS		/* must be last */
> +};
> +
>  struct wx {
>  	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
>  	DECLARE_BITMAP(state, WX_STATE_NBITS);
> +	DECLARE_BITMAP(flags, WX_PF_FLAGS_NBITS);
>  
>  	void *priv;
>  	u8 __iomem *hw_addr;
> @@ -1082,6 +1114,12 @@ struct wx {
>  	u64 hw_csum_rx_error;
>  	u64 alloc_rx_buff_failed;
>  
> +	unsigned int num_vfs;
> +	struct vf_data_storage *vfinfo;
> +	struct vf_macvlans vf_mvs;
> +	struct vf_macvlans *mv_list;
> +
> +	int (*setup_tc)(struct net_device *netdev, u8 tc);
>  	void (*do_reset)(struct net_device *netdev);
>  };
>  

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ