Commit e196ec75 authored by Jian Shen's avatar Jian Shen Committed by Jakub Kicinski
Browse files

net: hns3: add support for setting VF trust



This patch adds supports for setting VF trust by host. If specified
VF is trusted, then it can enable promisc(include allmulti mode).
If a trusted VF enabled promisc, and being untrusted, host will
disable promisc mode for this VF.

For VF will update its promisc mode from set_rx_mode now, so it's
unnecessary to set broadcst promisc mode when initialization or
reset.

Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
parent 22044f95
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_GET_LINK_MODE,	/* (VF -> PF) get the link mode of pf */
	HCLGE_MBX_PUSH_VLAN_INFO,	/* (PF -> VF) push port base vlan */
	HCLGE_MBX_GET_MEDIA_TYPE,       /* (VF -> PF) get media type */
	HCLGE_MBX_PUSH_PROMISC_INFO,	/* (PF -> VF) push vf promisc info */

	HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf reset status */
	HCLGE_MBX_PUSH_LINK_STATUS,	/* (M7 -> PF) get port link status */
+4 −0
Original line number Diff line number Diff line
@@ -370,6 +370,9 @@ struct hnae3_ae_dev {
 *   Set VF link status
 * set_vf_spoofchk
 *   Enable/disable spoof check for specified vf
 * set_vf_trust
 *   Enable/disable trust for specified vf, if the vf being trusted, then
 *   it can enable promisc mode
 */
struct hnae3_ae_ops {
	int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
@@ -541,6 +544,7 @@ struct hnae3_ae_ops {
				 int link_state);
	int (*set_vf_spoofchk)(struct hnae3_handle *handle, int vf,
			       bool enable);
	int (*set_vf_trust)(struct hnae3_handle *handle, int vf, bool enable);
};

struct hnae3_dcb_ops {
+11 −0
Original line number Diff line number Diff line
@@ -1656,6 +1656,16 @@ static int hns3_set_vf_spoofchk(struct net_device *netdev, int vf, bool enable)
	return handle->ae_algo->ops->set_vf_spoofchk(handle, vf, enable);
}

static int hns3_set_vf_trust(struct net_device *netdev, int vf, bool enable)
{
	struct hnae3_handle *handle = hns3_get_handle(netdev);

	if (!handle->ae_algo->ops->set_vf_trust)
		return -EOPNOTSUPP;

	return handle->ae_algo->ops->set_vf_trust(handle, vf, enable);
}

static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -1856,6 +1866,7 @@ static const struct net_device_ops hns3_nic_netdev_ops = {
	.ndo_vlan_rx_kill_vid	= hns3_vlan_rx_kill_vid,
	.ndo_set_vf_vlan	= hns3_ndo_set_vf_vlan,
	.ndo_set_vf_spoofchk	= hns3_set_vf_spoofchk,
	.ndo_set_vf_trust	= hns3_set_vf_trust,
#ifdef CONFIG_RFS_ACCEL
	.ndo_rx_flow_steer	= hns3_rx_flow_steer,
#endif
+0 −3
Original line number Diff line number Diff line
@@ -1090,9 +1090,6 @@ void hclge_cmd_setup_basic_desc(struct hclge_desc *desc,
				enum hclge_opcode_type opcode, bool is_read);
void hclge_cmd_reuse_desc(struct hclge_desc *desc, bool is_read);

int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
			       struct hclge_promisc_param *param);

enum hclge_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw,
					   struct hclge_desc *desc);
enum hclge_cmd_status hclge_cmd_mdio_read(struct hclge_hw *hw,
+51 −9
Original line number Diff line number Diff line
@@ -2889,6 +2889,7 @@ static int hclge_get_vf_config(struct hnae3_handle *handle, int vf,
	ivf->vf = vf;
	ivf->linkstate = vport->vf_info.link_state;
	ivf->spoofchk = vport->vf_info.spoofchk;
	ivf->trusted = vport->vf_info.trusted;
	ether_addr_copy(ivf->mac, vport->vf_info.mac);

	return 0;
@@ -4614,7 +4615,7 @@ static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle, int vector,
	return ret;
}

int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
				      struct hclge_promisc_param *param)
{
	struct hclge_promisc_cfg_cmd *req;
@@ -4642,8 +4643,9 @@ int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
	return ret;
}

void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
			      bool en_mc, bool en_bc, int vport_id)
static void hclge_promisc_param_init(struct hclge_promisc_param *param,
				     bool en_uc, bool en_mc, bool en_bc,
				     int vport_id)
{
	if (!param)
		return;
@@ -4658,12 +4660,21 @@ void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
	param->vf_id = vport_id;
}

int hclge_set_vport_promisc_mode(struct hclge_vport *vport, bool en_uc_pmc,
				 bool en_mc_pmc, bool en_bc_pmc)
{
	struct hclge_dev *hdev = vport->back;
	struct hclge_promisc_param param;

	hclge_promisc_param_init(&param, en_uc_pmc, en_mc_pmc, en_bc_pmc,
				 vport->vport_id);
	return hclge_cmd_set_promisc_mode(hdev, &param);
}

static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
				  bool en_mc_pmc)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
	struct hclge_promisc_param param;
	bool en_bc_pmc = true;

	/* For revision 0x20, if broadcast promisc enabled, vlan filter is
@@ -4673,9 +4684,8 @@ static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
	if (handle->pdev->revision == 0x20)
		en_bc_pmc = handle->netdev_flags & HNAE3_BPE ? true : false;

	hclge_promisc_param_init(&param, en_uc_pmc, en_mc_pmc, en_bc_pmc,
				 vport->vport_id);
	return hclge_cmd_set_promisc_mode(hdev, &param);
	return hclge_set_vport_promisc_mode(vport, en_uc_pmc, en_mc_pmc,
					    en_bc_pmc);
}

static int hclge_get_fd_mode(struct hclge_dev *hdev, u8 *fd_mode)
@@ -9479,6 +9489,37 @@ static int hclge_reset_vport_spoofchk(struct hclge_dev *hdev)
	return 0;
}

static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable)
{
	struct hclge_vport *vport = hclge_get_vport(handle);
	struct hclge_dev *hdev = vport->back;
	u32 new_trusted = enable ? 1 : 0;
	bool en_bc_pmc;
	int ret;

	vport = hclge_get_vf_vport(hdev, vf);
	if (!vport)
		return -EINVAL;

	if (vport->vf_info.trusted == new_trusted)
		return 0;

	/* Disable promisc mode for VF if it is not trusted any more. */
	if (!enable && vport->vf_info.promisc_enable) {
		en_bc_pmc = hdev->pdev->revision != 0x20;
		ret = hclge_set_vport_promisc_mode(vport, false, false,
						   en_bc_pmc);
		if (ret)
			return ret;
		vport->vf_info.promisc_enable = 0;
		hclge_inform_vf_promisc_info(vport);
	}

	vport->vf_info.trusted = new_trusted;

	return 0;
}

static void hclge_reset_vport_state(struct hclge_dev *hdev)
{
	struct hclge_vport *vport = hdev->vport;
@@ -10318,6 +10359,7 @@ static const struct hnae3_ae_ops hclge_ops = {
	.get_vf_config = hclge_get_vf_config,
	.set_vf_link_state = hclge_set_vf_link_state,
	.set_vf_spoofchk = hclge_set_vf_spoofchk,
	.set_vf_trust = hclge_set_vf_trust,
};

static struct hnae3_ae_algo ae_algo = {
Loading