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

net: hns3: add priv flags support to switch limit promisc mode



Currently, the tx unicast promisc is always enabled when promisc
mode on. If tx unicast promisc on, a function will receive all
unicast packet from other functions belong to the same port.
Add a ethtool private flag to control whether enable tx
unicast promisc. Then the function is able to filter the
unknown unicast packets from other function.

Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c43abe1a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ struct hclge_vf_to_pf_msg {
			u8 en_bc;
			u8 en_uc;
			u8 en_mc;
			u8 en_limit_promisc;
		};
		struct {
			u8 vector_id;
+8 −0
Original line number Diff line number Diff line
@@ -719,6 +719,11 @@ struct hnae3_roce_private_info {
#define HNAE3_UPE		(HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
#define HNAE3_MPE		(HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)

enum hnae3_pflag {
	HNAE3_PFLAG_LIMIT_PROMISC,
	HNAE3_PFLAG_MAX
};

struct hnae3_handle {
	struct hnae3_client *client;
	struct pci_dev *pdev;
@@ -741,6 +746,9 @@ struct hnae3_handle {

	/* Network interface message level enabled bits */
	u32 msg_enable;

	unsigned long supported_pflags;
	unsigned long priv_flags;
};

#define hnae3_set_field(origin, mask, shift, val) \
+3 −0
Original line number Diff line number Diff line
@@ -4226,6 +4226,9 @@ static int hns3_client_init(struct hnae3_handle *handle)

	set_bit(HNS3_NIC_STATE_INITED, &priv->state);

	if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
		set_bit(HNAE3_PFLAG_LIMIT_PROMISC, &handle->supported_pflags);

	if (netif_msg_drv(handle))
		hns3_info_show(priv);

+86 −0
Original line number Diff line number Diff line
@@ -18,6 +18,11 @@ struct hns3_sfp_type {
	u8 ext_type;
};

struct hns3_pflag_desc {
	char name[ETH_GSTRING_LEN];
	void (*handler)(struct net_device *netdev, bool enable);
};

/* tqp related stats */
#define HNS3_TQP_STAT(_string, _member)	{			\
	.stats_string = _string,				\
@@ -60,6 +65,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
	HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
};

#define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags)

#define HNS3_RXQ_STATS_COUNT ARRAY_SIZE(hns3_rxq_stats)

#define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
@@ -395,6 +402,23 @@ static void hns3_self_test(struct net_device *ndev,
	netif_dbg(h, drv, ndev, "self test end\n");
}

static void hns3_update_limit_promisc_mode(struct net_device *netdev,
					   bool enable)
{
	struct hnae3_handle *handle = hns3_get_handle(netdev);

	if (enable)
		set_bit(HNAE3_PFLAG_LIMIT_PROMISC, &handle->priv_flags);
	else
		clear_bit(HNAE3_PFLAG_LIMIT_PROMISC, &handle->priv_flags);

	hns3_request_update_promisc_mode(handle);
}

static const struct hns3_pflag_desc hns3_priv_flags[HNAE3_PFLAG_MAX] = {
	{ "limit_promisc",	hns3_update_limit_promisc_mode }
};

static int hns3_get_sset_count(struct net_device *netdev, int stringset)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -411,6 +435,9 @@ static int hns3_get_sset_count(struct net_device *netdev, int stringset)
	case ETH_SS_TEST:
		return ops->get_sset_count(h, stringset);

	case ETH_SS_PRIV_FLAGS:
		return HNAE3_PFLAG_MAX;

	default:
		return -EOPNOTSUPP;
	}
@@ -464,6 +491,7 @@ static void hns3_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
	struct hnae3_handle *h = hns3_get_handle(netdev);
	const struct hnae3_ae_ops *ops = h->ae_algo->ops;
	char *buff = (char *)data;
	int i;

	if (!ops->get_strings)
		return;
@@ -476,6 +504,13 @@ static void hns3_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
	case ETH_SS_TEST:
		ops->get_strings(h, stringset, data);
		break;
	case ETH_SS_PRIV_FLAGS:
		for (i = 0; i < HNS3_PRIV_FLAGS_LEN; i++) {
			snprintf(buff, ETH_GSTRING_LEN, "%s",
				 hns3_priv_flags[i].name);
			buff += ETH_GSTRING_LEN;
		}
		break;
	default:
		break;
	}
@@ -1517,6 +1552,53 @@ static int hns3_get_module_eeprom(struct net_device *netdev,
	return ops->get_module_eeprom(handle, ee->offset, ee->len, data);
}

static u32 hns3_get_priv_flags(struct net_device *netdev)
{
	struct hnae3_handle *handle = hns3_get_handle(netdev);

	return handle->priv_flags;
}

static int hns3_check_priv_flags(struct hnae3_handle *h, u32 changed)
{
	u32 i;

	for (i = 0; i < HNAE3_PFLAG_MAX; i++)
		if ((changed & BIT(i)) && !test_bit(i, &h->supported_pflags)) {
			netdev_err(h->netdev, "%s is unsupported\n",
				   hns3_priv_flags[i].name);
			return -EOPNOTSUPP;
		}

	return 0;
}

static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags)
{
	struct hnae3_handle *handle = hns3_get_handle(netdev);
	u32 changed = pflags ^ handle->priv_flags;
	int ret;
	u32 i;

	ret = hns3_check_priv_flags(handle, changed);
	if (ret)
		return ret;

	for (i = 0; i < HNAE3_PFLAG_MAX; i++) {
		if (changed & BIT(i)) {
			bool enable = !(handle->priv_flags & BIT(i));

			if (enable)
				handle->priv_flags |= BIT(i);
			else
				handle->priv_flags &= ~BIT(i);
			hns3_priv_flags[i].handler(netdev, enable);
		}
	}

	return 0;
}

#define HNS3_ETHTOOL_COALESCE	(ETHTOOL_COALESCE_USECS |		\
				 ETHTOOL_COALESCE_USE_ADAPTIVE |	\
				 ETHTOOL_COALESCE_RX_USECS_HIGH |	\
@@ -1547,6 +1629,8 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
	.get_link = hns3_get_link,
	.get_msglevel = hns3_get_msglevel,
	.set_msglevel = hns3_set_msglevel,
	.get_priv_flags = hns3_get_priv_flags,
	.set_priv_flags = hns3_set_priv_flags,
};

static const struct ethtool_ops hns3_ethtool_ops = {
@@ -1583,6 +1667,8 @@ static const struct ethtool_ops hns3_ethtool_ops = {
	.set_fecparam = hns3_set_fecparam,
	.get_module_info = hns3_get_module_info,
	.get_module_eeprom = hns3_get_module_eeprom,
	.get_priv_flags = hns3_get_priv_flags,
	.set_priv_flags = hns3_set_priv_flags,
};

void hns3_ethtool_set_ops(struct net_device *netdev)
+7 −1
Original line number Diff line number Diff line
@@ -4829,8 +4829,11 @@ static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle, int vector,
static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, u8 vf_id,
				      bool en_uc, bool en_mc, bool en_bc)
{
	struct hclge_vport *vport = &hdev->vport[vf_id];
	struct hnae3_handle *handle = &vport->nic;
	struct hclge_promisc_cfg_cmd *req;
	struct hclge_desc desc;
	bool uc_tx_en = en_uc;
	u8 promisc_cfg = 0;
	int ret;

@@ -4839,10 +4842,13 @@ static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, u8 vf_id,
	req = (struct hclge_promisc_cfg_cmd *)desc.data;
	req->vf_id = vf_id;

	if (test_bit(HNAE3_PFLAG_LIMIT_PROMISC, &handle->priv_flags))
		uc_tx_en = false;

	hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_RX_EN, en_uc ? 1 : 0);
	hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_RX_EN, en_mc ? 1 : 0);
	hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_RX_EN, en_bc ? 1 : 0);
	hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_TX_EN, en_uc ? 1 : 0);
	hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_TX_EN, uc_tx_en ? 1 : 0);
	hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_TX_EN, en_mc ? 1 : 0);
	hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_TX_EN, en_bc ? 1 : 0);
	req->extend_promisc = promisc_cfg;
Loading