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

Commit 7d982567 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mlx5-updates-2017-01-19' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
mlx5 and mlx5e updates 2017-01-19

This series includes some updates for mlx5 core and mlx5e netdevice driver.

From Leon, a small fix that remove an unnecessary print.

From Eli Cohen, a fix to the FW version printout in case of internal error.

From Eugenia Emantayev, two patches, the 1st adds mlx5 1pps (pulse per
second) mlx5 infrastructure support and the 2nd adds the necessary bits
for mlx5e ptp logic and structures.

From Mohamad, add support for s-tagged packet receive when in promiscuous
mode.

Form Gal Pressman, MCAM (Management capabilities mask register) and PCAM
(Ports capabilities mask register) registers infrastructure, those
registers are needed in order to query the different statistics registers
support in FW, in order for the driver to enable/disable query and
reporting them back to user.  On top of this infrastructure we've exposed
new set of statistics groups:
   - MPCNT: Physical layer statistical counters (For symbol errors)
   - PPCNT: PCIe performance counters

In addition to the statistics capabilities series we've moved the mlx5 HCA
capabilities fields to a dedicated struct under the driver private data.

At the end a small patch to update & query statistics in the most desired
order.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cc154783 3dd69e3d
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -1704,9 +1704,9 @@ static int parse_flow_attr(u32 *match_c, u32 *match_v,

		if (ib_spec->eth.mask.vlan_tag) {
			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
				 vlan_tag, 1);
				 cvlan_tag, 1);
			MLX5_SET(fte_match_set_lyr_2_4, headers_v,
				 vlan_tag, 1);
				 cvlan_tag, 1);

			MLX5_SET(fte_match_set_lyr_2_4, headers_c,
				 first_vid, ntohs(ib_spec->eth.mask.vlan_tag));
+6 −2
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ struct mlx5e_tstamp {
	struct mlx5_core_dev      *mdev;
	struct ptp_clock          *ptp;
	struct ptp_clock_info      ptp_info;
	u8                        *pps_pin_caps;
};

enum {
@@ -571,7 +572,8 @@ struct mlx5e_vlan_table {
	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
	struct mlx5_flow_handle	*active_vlans_rule[VLAN_N_VID];
	struct mlx5_flow_handle	*untagged_rule;
	struct mlx5_flow_handle	*any_vlan_rule;
	struct mlx5_flow_handle	*any_cvlan_rule;
	struct mlx5_flow_handle	*any_svlan_rule;
	bool			filter_disabled;
};

@@ -780,6 +782,8 @@ void mlx5e_fill_hwstamp(struct mlx5e_tstamp *clock, u64 timestamp,
			struct skb_shared_hwtstamps *hwts);
void mlx5e_timestamp_init(struct mlx5e_priv *priv);
void mlx5e_timestamp_cleanup(struct mlx5e_priv *priv);
void mlx5e_pps_event_handler(struct mlx5e_priv *priv,
			     struct ptp_clock_event *event);
int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr);
int mlx5e_hwstamp_get(struct net_device *dev, struct ifreq *ifr);
void mlx5e_modify_rx_cqe_compression(struct mlx5e_priv *priv, bool val);
+218 −0
Original line number Diff line number Diff line
@@ -37,6 +37,22 @@ enum {
	MLX5E_CYCLES_SHIFT	= 23
};

enum {
	MLX5E_PIN_MODE_IN		= 0x0,
	MLX5E_PIN_MODE_OUT		= 0x1,
};

enum {
	MLX5E_OUT_PATTERN_PULSE		= 0x0,
	MLX5E_OUT_PATTERN_PERIODIC	= 0x1,
};

enum {
	MLX5E_EVENT_MODE_DISABLE	= 0x0,
	MLX5E_EVENT_MODE_REPETETIVE	= 0x1,
	MLX5E_EVENT_MODE_ONCE_TILL_ARM	= 0x2,
};

void mlx5e_fill_hwstamp(struct mlx5e_tstamp *tstamp, u64 timestamp,
			struct skb_shared_hwtstamps *hwts)
{
@@ -189,6 +205,18 @@ static int mlx5e_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
	int neg_adj = 0;
	struct mlx5e_tstamp *tstamp = container_of(ptp, struct mlx5e_tstamp,
						  ptp_info);
	struct mlx5e_priv *priv =
		container_of(tstamp, struct mlx5e_priv, tstamp);

	if (MLX5_CAP_GEN(priv->mdev, pps_modify)) {
		u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};

		/* For future use need to add a loop for finding all 1PPS out pins */
		MLX5_SET(mtpps_reg, in, pin_mode, MLX5E_PIN_MODE_OUT);
		MLX5_SET(mtpps_reg, in, out_periodic_adjustment, delta & 0xFFFF);

		mlx5_set_mtpps(priv->mdev, in, sizeof(in));
	}

	if (delta < 0) {
		neg_adj = 1;
@@ -208,6 +236,124 @@ static int mlx5e_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
	return 0;
}

static int mlx5e_extts_configure(struct ptp_clock_info *ptp,
				 struct ptp_clock_request *rq,
				 int on)
{
	struct mlx5e_tstamp *tstamp =
		container_of(ptp, struct mlx5e_tstamp, ptp_info);
	struct mlx5e_priv *priv =
		container_of(tstamp, struct mlx5e_priv, tstamp);
	u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
	u8 pattern = 0;
	int pin = -1;
	int err = 0;

	if (!MLX5_CAP_GEN(priv->mdev, pps) ||
	    !MLX5_CAP_GEN(priv->mdev, pps_modify))
		return -EOPNOTSUPP;

	if (rq->extts.index >= tstamp->ptp_info.n_pins)
		return -EINVAL;

	if (on) {
		pin = ptp_find_pin(tstamp->ptp, PTP_PF_EXTTS, rq->extts.index);
		if (pin < 0)
			return -EBUSY;
	}

	if (rq->extts.flags & PTP_FALLING_EDGE)
		pattern = 1;

	MLX5_SET(mtpps_reg, in, pin, pin);
	MLX5_SET(mtpps_reg, in, pin_mode, MLX5E_PIN_MODE_IN);
	MLX5_SET(mtpps_reg, in, pattern, pattern);
	MLX5_SET(mtpps_reg, in, enable, on);

	err = mlx5_set_mtpps(priv->mdev, in, sizeof(in));
	if (err)
		return err;

	return mlx5_set_mtppse(priv->mdev, pin, 0,
			       MLX5E_EVENT_MODE_REPETETIVE & on);
}

static int mlx5e_perout_configure(struct ptp_clock_info *ptp,
				  struct ptp_clock_request *rq,
				  int on)
{
	struct mlx5e_tstamp *tstamp =
		container_of(ptp, struct mlx5e_tstamp, ptp_info);
	struct mlx5e_priv *priv =
		container_of(tstamp, struct mlx5e_priv, tstamp);
	u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
	u64 nsec_now, nsec_delta, time_stamp;
	u64 cycles_now, cycles_delta;
	struct timespec64 ts;
	unsigned long flags;
	int pin = -1;
	s64 ns;

	if (!MLX5_CAP_GEN(priv->mdev, pps_modify))
		return -EOPNOTSUPP;

	if (rq->perout.index >= tstamp->ptp_info.n_pins)
		return -EINVAL;

	if (on) {
		pin = ptp_find_pin(tstamp->ptp, PTP_PF_PEROUT,
				   rq->perout.index);
		if (pin < 0)
			return -EBUSY;
	}

	ts.tv_sec = rq->perout.period.sec;
	ts.tv_nsec = rq->perout.period.nsec;
	ns = timespec64_to_ns(&ts);
	if (on)
		if ((ns >> 1) != 500000000LL)
			return -EINVAL;
	ts.tv_sec = rq->perout.start.sec;
	ts.tv_nsec = rq->perout.start.nsec;
	ns = timespec64_to_ns(&ts);
	cycles_now = mlx5_read_internal_timer(tstamp->mdev);
	write_lock_irqsave(&tstamp->lock, flags);
	nsec_now = timecounter_cyc2time(&tstamp->clock, cycles_now);
	nsec_delta = ns - nsec_now;
	cycles_delta = div64_u64(nsec_delta << tstamp->cycles.shift,
				 tstamp->cycles.mult);
	write_unlock_irqrestore(&tstamp->lock, flags);
	time_stamp = cycles_now + cycles_delta;
	MLX5_SET(mtpps_reg, in, pin, pin);
	MLX5_SET(mtpps_reg, in, pin_mode, MLX5E_PIN_MODE_OUT);
	MLX5_SET(mtpps_reg, in, pattern, MLX5E_OUT_PATTERN_PERIODIC);
	MLX5_SET(mtpps_reg, in, enable, on);
	MLX5_SET64(mtpps_reg, in, time_stamp, time_stamp);

	return mlx5_set_mtpps(priv->mdev, in, sizeof(in));
}

static int mlx5e_ptp_enable(struct ptp_clock_info *ptp,
			    struct ptp_clock_request *rq,
			    int on)
{
	switch (rq->type) {
	case PTP_CLK_REQ_EXTTS:
		return mlx5e_extts_configure(ptp, rq, on);
	case PTP_CLK_REQ_PEROUT:
		return mlx5e_perout_configure(ptp, rq, on);
	default:
		return -EOPNOTSUPP;
	}
	return 0;
}

static int mlx5e_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
			    enum ptp_pin_function func, unsigned int chan)
{
	return (func == PTP_PF_PHYSYNC) ? -EOPNOTSUPP : 0;
}

static const struct ptp_clock_info mlx5e_ptp_clock_info = {
	.owner		= THIS_MODULE,
	.max_adj	= 100000000,
@@ -221,6 +367,7 @@ static const struct ptp_clock_info mlx5e_ptp_clock_info = {
	.gettime64	= mlx5e_ptp_gettime,
	.settime64	= mlx5e_ptp_settime,
	.enable		= NULL,
	.verify		= NULL,
};

static void mlx5e_timestamp_init_config(struct mlx5e_tstamp *tstamp)
@@ -229,6 +376,62 @@ static void mlx5e_timestamp_init_config(struct mlx5e_tstamp *tstamp)
	tstamp->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
}

static int mlx5e_init_pin_config(struct mlx5e_tstamp *tstamp)
{
	int i;

	tstamp->ptp_info.pin_config =
		kzalloc(sizeof(*tstamp->ptp_info.pin_config) *
			       tstamp->ptp_info.n_pins, GFP_KERNEL);
	if (!tstamp->ptp_info.pin_config)
		return -ENOMEM;
	tstamp->ptp_info.enable = mlx5e_ptp_enable;
	tstamp->ptp_info.verify = mlx5e_ptp_verify;

	for (i = 0; i < tstamp->ptp_info.n_pins; i++) {
		snprintf(tstamp->ptp_info.pin_config[i].name,
			 sizeof(tstamp->ptp_info.pin_config[i].name),
			 "mlx5_pps%d", i);
		tstamp->ptp_info.pin_config[i].index = i;
		tstamp->ptp_info.pin_config[i].func = PTP_PF_NONE;
		tstamp->ptp_info.pin_config[i].chan = i;
	}

	return 0;
}

static void mlx5e_get_pps_caps(struct mlx5e_priv *priv,
			       struct mlx5e_tstamp *tstamp)
{
	u32 out[MLX5_ST_SZ_DW(mtpps_reg)] = {0};

	mlx5_query_mtpps(priv->mdev, out, sizeof(out));

	tstamp->ptp_info.n_pins = MLX5_GET(mtpps_reg, out,
					   cap_number_of_pps_pins);
	tstamp->ptp_info.n_ext_ts = MLX5_GET(mtpps_reg, out,
					     cap_max_num_of_pps_in_pins);
	tstamp->ptp_info.n_per_out = MLX5_GET(mtpps_reg, out,
					      cap_max_num_of_pps_out_pins);

	tstamp->pps_pin_caps[0] = MLX5_GET(mtpps_reg, out, cap_pin_0_mode);
	tstamp->pps_pin_caps[1] = MLX5_GET(mtpps_reg, out, cap_pin_1_mode);
	tstamp->pps_pin_caps[2] = MLX5_GET(mtpps_reg, out, cap_pin_2_mode);
	tstamp->pps_pin_caps[3] = MLX5_GET(mtpps_reg, out, cap_pin_3_mode);
	tstamp->pps_pin_caps[4] = MLX5_GET(mtpps_reg, out, cap_pin_4_mode);
	tstamp->pps_pin_caps[5] = MLX5_GET(mtpps_reg, out, cap_pin_5_mode);
	tstamp->pps_pin_caps[6] = MLX5_GET(mtpps_reg, out, cap_pin_6_mode);
	tstamp->pps_pin_caps[7] = MLX5_GET(mtpps_reg, out, cap_pin_7_mode);
}

void mlx5e_pps_event_handler(struct mlx5e_priv *priv,
			     struct ptp_clock_event *event)
{
	struct mlx5e_tstamp *tstamp = &priv->tstamp;

	ptp_clock_event(tstamp->ptp, event);
}

void mlx5e_timestamp_init(struct mlx5e_priv *priv)
{
	struct mlx5e_tstamp *tstamp = &priv->tstamp;
@@ -272,6 +475,18 @@ void mlx5e_timestamp_init(struct mlx5e_priv *priv)
	tstamp->ptp_info = mlx5e_ptp_clock_info;
	snprintf(tstamp->ptp_info.name, 16, "mlx5 ptp");

	/* Initialize 1PPS data structures */
#define MAX_PIN_NUM	8
	tstamp->pps_pin_caps = kzalloc(sizeof(u8) * MAX_PIN_NUM, GFP_KERNEL);
	if (tstamp->pps_pin_caps) {
		if (MLX5_CAP_GEN(priv->mdev, pps))
			mlx5e_get_pps_caps(priv, tstamp);
		if (tstamp->ptp_info.n_pins)
			mlx5e_init_pin_config(tstamp);
	} else {
		mlx5_core_warn(priv->mdev, "1PPS initialization failed\n");
	}

	tstamp->ptp = ptp_clock_register(&tstamp->ptp_info,
					 &priv->mdev->pdev->dev);
	if (IS_ERR(tstamp->ptp)) {
@@ -293,5 +508,8 @@ void mlx5e_timestamp_cleanup(struct mlx5e_priv *priv)
		priv->tstamp.ptp = NULL;
	}

	kfree(tstamp->pps_pin_caps);
	kfree(tstamp->ptp_info.pin_config);

	cancel_delayed_work_sync(&tstamp->overflow_work);
}
+18 −1
Original line number Diff line number Diff line
@@ -170,7 +170,8 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
	case ETH_SS_STATS:
		return NUM_SW_COUNTERS +
		       MLX5E_NUM_Q_CNTRS(priv) +
		       NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS +
		       NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS(priv) +
		       NUM_PCIE_COUNTERS(priv) +
		       MLX5E_NUM_RQ_STATS(priv) +
		       MLX5E_NUM_SQ_STATS(priv) +
		       MLX5E_NUM_PFC_COUNTERS(priv) +
@@ -218,6 +219,14 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
		strcpy(data + (idx++) * ETH_GSTRING_LEN,
		       pport_2819_stats_desc[i].format);

	for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_COUNTERS(priv); i++)
		strcpy(data + (idx++) * ETH_GSTRING_LEN,
		       pport_phy_statistical_stats_desc[i].format);

	for (i = 0; i < NUM_PCIE_PERF_COUNTERS(priv); i++)
		strcpy(data + (idx++) * ETH_GSTRING_LEN,
		       pcie_perf_stats_desc[i].format);

	for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
		for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
			sprintf(data + (idx++) * ETH_GSTRING_LEN,
@@ -330,6 +339,14 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
		data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2819_counters,
						  pport_2819_stats_desc, i);

	for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_COUNTERS(priv); i++)
		data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.phy_statistical_counters,
						  pport_phy_statistical_stats_desc, i);

	for (i = 0; i < NUM_PCIE_PERF_COUNTERS(priv); i++)
		data[idx++] = MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_perf_counters,
						  pcie_perf_stats_desc, i);

	for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
		for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
			data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
+69 −22
Original line number Diff line number Diff line
@@ -150,7 +150,8 @@ static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv)

enum mlx5e_vlan_rule_type {
	MLX5E_VLAN_RULE_TYPE_UNTAGGED,
	MLX5E_VLAN_RULE_TYPE_ANY_VID,
	MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID,
	MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID,
	MLX5E_VLAN_RULE_TYPE_MATCH_VID,
};

@@ -172,19 +173,31 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
	dest.ft = priv->fs.l2.ft.t;

	spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
	MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.vlan_tag);


	switch (rule_type) {
	case MLX5E_VLAN_RULE_TYPE_UNTAGGED:
		rule_p = &priv->fs.vlan.untagged_rule;
		MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
				 outer_headers.cvlan_tag);
		break;
	case MLX5E_VLAN_RULE_TYPE_ANY_VID:
		rule_p = &priv->fs.vlan.any_vlan_rule;
		MLX5_SET(fte_match_param, spec->match_value, outer_headers.vlan_tag, 1);
	case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID:
		rule_p = &priv->fs.vlan.any_cvlan_rule;
		MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
				 outer_headers.cvlan_tag);
		MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1);
		break;
	case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID:
		rule_p = &priv->fs.vlan.any_svlan_rule;
		MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
				 outer_headers.svlan_tag);
		MLX5_SET(fte_match_param, spec->match_value, outer_headers.svlan_tag, 1);
		break;
	default: /* MLX5E_VLAN_RULE_TYPE_MATCH_VID */
		rule_p = &priv->fs.vlan.active_vlans_rule[vid];
		MLX5_SET(fte_match_param, spec->match_value, outer_headers.vlan_tag, 1);
		MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
				 outer_headers.cvlan_tag);
		MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1);
		MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
				 outer_headers.first_vid);
		MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid,
@@ -235,10 +248,16 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
			priv->fs.vlan.untagged_rule = NULL;
		}
		break;
	case MLX5E_VLAN_RULE_TYPE_ANY_VID:
		if (priv->fs.vlan.any_vlan_rule) {
			mlx5_del_flow_rules(priv->fs.vlan.any_vlan_rule);
			priv->fs.vlan.any_vlan_rule = NULL;
	case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID:
		if (priv->fs.vlan.any_cvlan_rule) {
			mlx5_del_flow_rules(priv->fs.vlan.any_cvlan_rule);
			priv->fs.vlan.any_cvlan_rule = NULL;
		}
		break;
	case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID:
		if (priv->fs.vlan.any_svlan_rule) {
			mlx5_del_flow_rules(priv->fs.vlan.any_svlan_rule);
			priv->fs.vlan.any_svlan_rule = NULL;
		}
		break;
	case MLX5E_VLAN_RULE_TYPE_MATCH_VID:
@@ -252,6 +271,23 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
	}
}

static void mlx5e_del_any_vid_rules(struct mlx5e_priv *priv)
{
	mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
	mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0);
}

static int mlx5e_add_any_vid_rules(struct mlx5e_priv *priv)
{
	int err;

	err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
	if (err)
		return err;

	return mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0);
}

void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv)
{
	if (!priv->fs.vlan.filter_disabled)
@@ -260,7 +296,7 @@ void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv)
	priv->fs.vlan.filter_disabled = false;
	if (priv->netdev->flags & IFF_PROMISC)
		return;
	mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
	mlx5e_del_any_vid_rules(priv);
}

void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv)
@@ -271,7 +307,7 @@ void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv)
	priv->fs.vlan.filter_disabled = true;
	if (priv->netdev->flags & IFF_PROMISC)
		return;
	mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
	mlx5e_add_any_vid_rules(priv);
}

int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto,
@@ -308,7 +344,7 @@ static void mlx5e_add_vlan_rules(struct mlx5e_priv *priv)

	if (priv->fs.vlan.filter_disabled &&
	    !(priv->netdev->flags & IFF_PROMISC))
		mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
		mlx5e_add_any_vid_rules(priv);
}

static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
@@ -323,7 +359,7 @@ static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)

	if (priv->fs.vlan.filter_disabled &&
	    !(priv->netdev->flags & IFF_PROMISC))
		mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID, 0);
		mlx5e_del_any_vid_rules(priv);
}

#define mlx5e_for_each_hash_node(hn, tmp, hash, i) \
@@ -503,8 +539,7 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
	if (enable_promisc) {
		mlx5e_add_l2_flow_rule(priv, &ea->promisc, MLX5E_PROMISC);
		if (!priv->fs.vlan.filter_disabled)
			mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
					    0);
			mlx5e_add_any_vid_rules(priv);
	}
	if (enable_allmulti)
		mlx5e_add_l2_flow_rule(priv, &ea->allmulti, MLX5E_ALLMULTI);
@@ -519,8 +554,7 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
		mlx5e_del_l2_flow_rule(priv, &ea->allmulti);
	if (disable_promisc) {
		if (!priv->fs.vlan.filter_disabled)
			mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_VID,
					    0);
			mlx5e_del_any_vid_rules(priv);
		mlx5e_del_l2_flow_rule(priv, &ea->promisc);
	}

@@ -976,11 +1010,13 @@ static int mlx5e_create_l2_table(struct mlx5e_priv *priv)
	return err;
}

#define MLX5E_NUM_VLAN_GROUPS	2
#define MLX5E_NUM_VLAN_GROUPS	3
#define MLX5E_VLAN_GROUP0_SIZE	BIT(12)
#define MLX5E_VLAN_GROUP1_SIZE	BIT(1)
#define MLX5E_VLAN_GROUP2_SIZE	BIT(0)
#define MLX5E_VLAN_TABLE_SIZE	(MLX5E_VLAN_GROUP0_SIZE +\
				 MLX5E_VLAN_GROUP1_SIZE)
				 MLX5E_VLAN_GROUP1_SIZE +\
				 MLX5E_VLAN_GROUP2_SIZE)

static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in,
					    int inlen)
@@ -991,7 +1027,7 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in

	memset(in, 0, inlen);
	MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
	MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.vlan_tag);
	MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag);
	MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid);
	MLX5_SET_CFG(in, start_flow_index, ix);
	ix += MLX5E_VLAN_GROUP0_SIZE;
@@ -1003,7 +1039,7 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in

	memset(in, 0, inlen);
	MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
	MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.vlan_tag);
	MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag);
	MLX5_SET_CFG(in, start_flow_index, ix);
	ix += MLX5E_VLAN_GROUP1_SIZE;
	MLX5_SET_CFG(in, end_flow_index, ix - 1);
@@ -1012,6 +1048,17 @@ static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in
		goto err_destroy_groups;
	ft->num_groups++;

	memset(in, 0, inlen);
	MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
	MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag);
	MLX5_SET_CFG(in, start_flow_index, ix);
	ix += MLX5E_VLAN_GROUP2_SIZE;
	MLX5_SET_CFG(in, end_flow_index, ix - 1);
	ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
	if (IS_ERR(ft->g[ft->num_groups]))
		goto err_destroy_groups;
	ft->num_groups++;

	return 0;

err_destroy_groups:
Loading