Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 139ce90a authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hns3-promisc-next'



Salil Mehta says:

====================
Fixes & small enhancements related to the promisc mode in HNS3

This patch-set presents some fixes and enhancements related to promiscuous
mode and MAC VLAN Table full condition in HNS3 Ethernet Driver.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5886d932 829edbd8
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -503,6 +503,15 @@ struct hnae3_unic_private_info {
#define HNAE3_SUPPORT_VF	      BIT(3)
#define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK	BIT(4)

#define HNAE3_USER_UPE		BIT(0)	/* unicast promisc enabled by user */
#define HNAE3_USER_MPE		BIT(1)	/* mulitcast promisc enabled by user */
#define HNAE3_BPE		BIT(2)	/* broadcast promisc enable */
#define HNAE3_OVERFLOW_UPE	BIT(3)	/* unicast mac vlan overflow */
#define HNAE3_OVERFLOW_MPE	BIT(4)	/* multicast mac vlan overflow */
#define HNAE3_VLAN_FLTR		BIT(5)	/* enable vlan filter */
#define HNAE3_UPE		(HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
#define HNAE3_MPE		(HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)

struct hnae3_handle {
	struct hnae3_client *client;
	struct pci_dev *pdev;
@@ -521,6 +530,8 @@ struct hnae3_handle {
	};

	u32 numa_node_mask;	/* for multi-chip support */

	u8 netdev_flags;
};

#define hnae3_set_field(origin, mask, shift, val) \
+73 −11
Original line number Diff line number Diff line
@@ -459,23 +459,81 @@ static int hns3_nic_mc_unsync(struct net_device *netdev,
	return 0;
}

static u8 hns3_get_netdev_flags(struct net_device *netdev)
{
	u8 flags = 0;

	if (netdev->flags & IFF_PROMISC) {
		flags = HNAE3_USER_UPE | HNAE3_USER_MPE;
	} else {
		flags |= HNAE3_VLAN_FLTR;
		if (netdev->flags & IFF_ALLMULTI)
			flags |= HNAE3_USER_MPE;
	}

	return flags;
}

static void hns3_nic_set_rx_mode(struct net_device *netdev)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
	u8 new_flags;
	int ret;

	if (h->ae_algo->ops->set_promisc_mode) {
		if (netdev->flags & IFF_PROMISC)
			h->ae_algo->ops->set_promisc_mode(h, true, true);
		else if (netdev->flags & IFF_ALLMULTI)
			h->ae_algo->ops->set_promisc_mode(h, false, true);
		else
			h->ae_algo->ops->set_promisc_mode(h, false, false);
	}
	if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync))
	new_flags = hns3_get_netdev_flags(netdev);

	ret = __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
	if (ret) {
		netdev_err(netdev, "sync uc address fail\n");
		if (ret == -ENOSPC)
			new_flags |= HNAE3_OVERFLOW_UPE;
	}

	if (netdev->flags & IFF_MULTICAST) {
		if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync))
		ret = __dev_mc_sync(netdev, hns3_nic_mc_sync,
				    hns3_nic_mc_unsync);
		if (ret) {
			netdev_err(netdev, "sync mc address fail\n");
			if (ret == -ENOSPC)
				new_flags |= HNAE3_OVERFLOW_MPE;
		}
	}

	hns3_update_promisc_mode(netdev, new_flags);
	/* User mode Promisc mode enable and vlan filtering is disabled to
	 * let all packets in. MAC-VLAN Table overflow Promisc enabled and
	 * vlan fitering is enabled
	 */
	hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
	h->netdev_flags = new_flags;
}

void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
{
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	struct hnae3_handle *h = priv->ae_handle;

	if (h->ae_algo->ops->set_promisc_mode) {
		h->ae_algo->ops->set_promisc_mode(h,
						  promisc_flags & HNAE3_UPE,
						  promisc_flags & HNAE3_MPE);
	}
}

void hns3_enable_vlan_filter(struct net_device *netdev, bool enable)
{
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	struct hnae3_handle *h = priv->ae_handle;
	bool last_state;

	if (h->pdev->revision >= 0x21 && h->ae_algo->ops->enable_vlan_filter) {
		last_state = h->netdev_flags & HNAE3_VLAN_FLTR ? true : false;
		if (enable != last_state) {
			netdev_info(netdev,
				    "%s vlan filter\n",
				    enable ? "enable" : "disable");
			h->ae_algo->ops->enable_vlan_filter(h, enable);
		}
	}
}

@@ -3607,11 +3665,15 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
{
	struct net_device *netdev = handle->kinfo.netdev;
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	bool vlan_filter_enable;
	int ret;

	hns3_init_mac_addr(netdev, false);
	hns3_nic_set_rx_mode(netdev);
	hns3_recover_hw_addr(netdev);
	hns3_update_promisc_mode(netdev, handle->netdev_flags);
	vlan_filter_enable = netdev->flags & IFF_PROMISC ? false : true;
	hns3_enable_vlan_filter(netdev, vlan_filter_enable);


	/* Hardware table is only clear when pf resets */
	if (!(handle->flags & HNAE3_SUPPORT_VF))
+3 −0
Original line number Diff line number Diff line
@@ -640,6 +640,9 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector,
void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
				 u32 rl_value);

void hns3_enable_vlan_filter(struct net_device *netdev, bool enable);
void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);

#ifdef CONFIG_HNS3_DCB
void hns3_dcbnl_setup(struct hnae3_handle *handle);
#else
+9 −1
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct hns3_link_mode_mapping {
static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
{
	struct hnae3_handle *h = hns3_get_handle(ndev);
	bool vlan_filter_enable;
	int ret;

	if (!h->ae_algo->ops->set_loopback ||
@@ -91,7 +92,14 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
	if (ret)
		return ret;

	h->ae_algo->ops->set_promisc_mode(h, en, en);
	if (en) {
		h->ae_algo->ops->set_promisc_mode(h, true, true);
	} else {
		/* recover promisc mode before loopback test */
		hns3_update_promisc_mode(ndev, h->netdev_flags);
		vlan_filter_enable = ndev->flags & IFF_PROMISC ? false : true;
		hns3_enable_vlan_filter(ndev, vlan_filter_enable);
	}

	return ret;
}
+7 −2
Original line number Diff line number Diff line
@@ -5606,6 +5606,10 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
		hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
					   HCLGE_FILTER_FE_EGRESS_V1_B, enable);
	}
	if (enable)
		handle->netdev_flags |= HNAE3_VLAN_FLTR;
	else
		handle->netdev_flags &= ~HNAE3_VLAN_FLTR;
}

static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
@@ -5902,7 +5906,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
{
#define HCLGE_DEF_VLAN_TYPE		0x8100

	struct hnae3_handle *handle;
	struct hnae3_handle *handle = &hdev->vport[0].nic;
	struct hclge_vport *vport;
	int ret;
	int i;
@@ -5925,6 +5929,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
			return ret;
	}

	handle->netdev_flags |= HNAE3_VLAN_FLTR;

	hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
	hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE;
	hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
@@ -5969,7 +5975,6 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
			return ret;
	}

	handle = &hdev->vport[0].nic;
	return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
}