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

Merge tag 'mlx5-updates-2021-03-12' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
mlx5-updates-2021-03-12

1) TC support for ICMP parameters
2) TC connection tracking with mirroring
3) A round of trivial fixups and cleanups
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents bfdfe7fc a3222a2d
Loading
Loading
Loading
Loading
+18 −14
Original line number Diff line number Diff line
@@ -263,15 +263,15 @@ static int verify_signature(struct mlx5_cmd_work_ent *ent)
	return 0;
}

static void dump_buf(void *buf, int size, int data_only, int offset)
static void dump_buf(void *buf, int size, int data_only, int offset, int idx)
{
	__be32 *p = buf;
	int i;

	for (i = 0; i < size; i += 16) {
		pr_debug("%03x: %08x %08x %08x %08x\n", offset, be32_to_cpu(p[0]),
			 be32_to_cpu(p[1]), be32_to_cpu(p[2]),
			 be32_to_cpu(p[3]));
		pr_debug("cmd[%d]: %03x: %08x %08x %08x %08x\n", idx, offset,
			 be32_to_cpu(p[0]), be32_to_cpu(p[1]),
			 be32_to_cpu(p[2]), be32_to_cpu(p[3]));
		p += 4;
		offset += 16;
	}
@@ -802,39 +802,41 @@ static void dump_command(struct mlx5_core_dev *dev,
	int dump_len;
	int i;

	mlx5_core_dbg(dev, "cmd[%d]: start dump\n", ent->idx);
	data_only = !!(mlx5_core_debug_mask & (1 << MLX5_CMD_DATA));

	if (data_only)
		mlx5_core_dbg_mask(dev, 1 << MLX5_CMD_DATA,
				   "dump command data %s(0x%x) %s\n",
				   mlx5_command_str(op), op,
				   "cmd[%d]: dump command data %s(0x%x) %s\n",
				   ent->idx, mlx5_command_str(op), op,
				   input ? "INPUT" : "OUTPUT");
	else
		mlx5_core_dbg(dev, "dump command %s(0x%x) %s\n",
			      mlx5_command_str(op), op,
		mlx5_core_dbg(dev, "cmd[%d]: dump command %s(0x%x) %s\n",
			      ent->idx, mlx5_command_str(op), op,
			      input ? "INPUT" : "OUTPUT");

	if (data_only) {
		if (input) {
			dump_buf(ent->lay->in, sizeof(ent->lay->in), 1, offset);
			dump_buf(ent->lay->in, sizeof(ent->lay->in), 1, offset, ent->idx);
			offset += sizeof(ent->lay->in);
		} else {
			dump_buf(ent->lay->out, sizeof(ent->lay->out), 1, offset);
			dump_buf(ent->lay->out, sizeof(ent->lay->out), 1, offset, ent->idx);
			offset += sizeof(ent->lay->out);
		}
	} else {
		dump_buf(ent->lay, sizeof(*ent->lay), 0, offset);
		dump_buf(ent->lay, sizeof(*ent->lay), 0, offset, ent->idx);
		offset += sizeof(*ent->lay);
	}

	for (i = 0; i < n && next; i++)  {
		if (data_only) {
			dump_len = min_t(int, MLX5_CMD_DATA_BLOCK_SIZE, msg->len - offset);
			dump_buf(next->buf, dump_len, 1, offset);
			dump_buf(next->buf, dump_len, 1, offset, ent->idx);
			offset += MLX5_CMD_DATA_BLOCK_SIZE;
		} else {
			mlx5_core_dbg(dev, "command block:\n");
			dump_buf(next->buf, sizeof(struct mlx5_cmd_prot_block), 0, offset);
			mlx5_core_dbg(dev, "cmd[%d]: command block:\n", ent->idx);
			dump_buf(next->buf, sizeof(struct mlx5_cmd_prot_block), 0, offset,
				 ent->idx);
			offset += sizeof(struct mlx5_cmd_prot_block);
		}
		next = next->next;
@@ -842,6 +844,8 @@ static void dump_command(struct mlx5_core_dev *dev,

	if (data_only)
		pr_debug("\n");

	mlx5_core_dbg(dev, "cmd[%d]: end dump\n", ent->idx);
}

static u16 msg_to_opcode(struct mlx5_cmd_msg *in)
+2 −2
Original line number Diff line number Diff line
@@ -137,12 +137,12 @@ static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
		 * unregistering devlink instance while holding devlink_mutext.
		 * Hence, do not support reload.
		 */
		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated\n");
		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported when SFs are allocated");
		return -EOPNOTSUPP;
	}

	if (mlx5_lag_is_active(dev)) {
		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode\n");
		NL_SET_ERR_MSG_MOD(extack, "reload is unsupported in Lag mode");
		return -EOPNOTSUPP;
	}

+4 −0
Original line number Diff line number Diff line
@@ -1797,6 +1797,10 @@ __mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *ct_priv,
	ct_flow->post_ct_attr->prio = 0;
	ct_flow->post_ct_attr->ft = ct_priv->post_ct;

	/* Splits were handled before CT */
	if (ct_priv->ns_type == MLX5_FLOW_NAMESPACE_FDB)
		ct_flow->post_ct_attr->esw_attr->split_count = 0;

	ct_flow->post_ct_attr->inner_match_level = MLX5_MATCH_NONE;
	ct_flow->post_ct_attr->outer_match_level = MLX5_MATCH_NONE;
	ct_flow->post_ct_attr->action &= ~(MLX5_FLOW_CONTEXT_ACTION_DECAP);
+1 −0
Original line number Diff line number Diff line
@@ -669,6 +669,7 @@ int mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
						 get_cqe_opcode(cqe));
				mlx5e_dump_error_cqe(&sq->cq, sq->sqn,
						     (struct mlx5_err_cqe *)cqe);
				mlx5_wq_cyc_wqe_dump(&sq->wq, ci, wi->num_wqebbs);
				if (!test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state))
					queue_work(cq->priv->wq, &sq->recover_work);
				break;
+70 −12
Original line number Diff line number Diff line
@@ -445,12 +445,16 @@ static void mlx5e_hairpin_destroy_transport(struct mlx5e_hairpin *hp)
	mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn);
}

static void mlx5e_hairpin_fill_rqt_rqns(struct mlx5e_hairpin *hp, void *rqtc)
static int mlx5e_hairpin_fill_rqt_rqns(struct mlx5e_hairpin *hp, void *rqtc)
{
	u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE], rqn;
	u32 *indirection_rqt, rqn;
	struct mlx5e_priv *priv = hp->func_priv;
	int i, ix, sz = MLX5E_INDIR_RQT_SIZE;

	indirection_rqt = kzalloc(sz, GFP_KERNEL);
	if (!indirection_rqt)
		return -ENOMEM;

	mlx5e_build_default_indir_rqt(indirection_rqt, sz,
				      hp->num_channels);

@@ -462,6 +466,9 @@ static void mlx5e_hairpin_fill_rqt_rqns(struct mlx5e_hairpin *hp, void *rqtc)
		rqn = hp->pair->rqn[ix];
		MLX5_SET(rqtc, rqtc, rq_num[i], rqn);
	}

	kfree(indirection_rqt);
	return 0;
}

static int mlx5e_hairpin_create_indirect_rqt(struct mlx5e_hairpin *hp)
@@ -482,12 +489,15 @@ static int mlx5e_hairpin_create_indirect_rqt(struct mlx5e_hairpin *hp)
	MLX5_SET(rqtc, rqtc, rqt_actual_size, sz);
	MLX5_SET(rqtc, rqtc, rqt_max_size, sz);

	mlx5e_hairpin_fill_rqt_rqns(hp, rqtc);
	err = mlx5e_hairpin_fill_rqt_rqns(hp, rqtc);
	if (err)
		goto out;

	err = mlx5_core_create_rqt(mdev, in, inlen, &hp->indir_rqt.rqtn);
	if (!err)
		hp->indir_rqt.enabled = true;

out:
	kvfree(in);
	return err;
}
@@ -1077,18 +1087,22 @@ mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
	if (flow_flag_test(flow, CT)) {
		mod_hdr_acts = &attr->parse_attr->mod_hdr_acts;

		return mlx5_tc_ct_flow_offload(get_ct_priv(flow->priv),
		rule = mlx5_tc_ct_flow_offload(get_ct_priv(flow->priv),
					       flow, spec, attr,
					       mod_hdr_acts);
	} else {
		rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
	}

	rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
	if (IS_ERR(rule))
		return rule;

	if (attr->esw_attr->split_count) {
		flow->rule[1] = mlx5_eswitch_add_fwd_rule(esw, spec, attr);
		if (IS_ERR(flow->rule[1])) {
			if (flow_flag_test(flow, CT))
				mlx5_tc_ct_delete_flow(get_ct_priv(flow->priv), flow, attr);
			else
				mlx5_eswitch_del_offloaded_rule(esw, rule, attr);
			return flow->rule[1];
		}
@@ -1947,6 +1961,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
				    misc_parameters);
	void *misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
				    misc_parameters);
	void *misc_c_3 = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
				    misc_parameters_3);
	void *misc_v_3 = MLX5_ADDR_OF(fte_match_param, spec->match_value,
				    misc_parameters_3);
	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
	struct flow_dissector *dissector = rule->match.dissector;
	u16 addr_type = 0;
@@ -1976,6 +1994,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
	      BIT(FLOW_DISSECTOR_KEY_CT) |
	      BIT(FLOW_DISSECTOR_KEY_ENC_IP) |
	      BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) |
	      BIT(FLOW_DISSECTOR_KEY_ICMP) |
	      BIT(FLOW_DISSECTOR_KEY_MPLS))) {
		NL_SET_ERR_MSG_MOD(extack, "Unsupported key");
		netdev_dbg(priv->netdev, "Unsupported key used: 0x%x\n",
@@ -2295,7 +2314,49 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
		if (match.mask->flags)
			*match_level = MLX5_MATCH_L4;
	}
	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ICMP)) {
		struct flow_match_icmp match;

		flow_rule_match_icmp(rule, &match);
		switch (ip_proto) {
		case IPPROTO_ICMP:
			if (!(MLX5_CAP_GEN(priv->mdev, flex_parser_protocols) &
			      MLX5_FLEX_PROTO_ICMP))
				return -EOPNOTSUPP;
			MLX5_SET(fte_match_set_misc3, misc_c_3, icmp_type,
				 match.mask->type);
			MLX5_SET(fte_match_set_misc3, misc_v_3, icmp_type,
				 match.key->type);
			MLX5_SET(fte_match_set_misc3, misc_c_3, icmp_code,
				 match.mask->code);
			MLX5_SET(fte_match_set_misc3, misc_v_3, icmp_code,
				 match.key->code);
			break;
		case IPPROTO_ICMPV6:
			if (!(MLX5_CAP_GEN(priv->mdev, flex_parser_protocols) &
			      MLX5_FLEX_PROTO_ICMPV6))
				return -EOPNOTSUPP;
			MLX5_SET(fte_match_set_misc3, misc_c_3, icmpv6_type,
				 match.mask->type);
			MLX5_SET(fte_match_set_misc3, misc_v_3, icmpv6_type,
				 match.key->type);
			MLX5_SET(fte_match_set_misc3, misc_c_3, icmpv6_code,
				 match.mask->code);
			MLX5_SET(fte_match_set_misc3, misc_v_3, icmpv6_code,
				 match.key->code);
			break;
		default:
			NL_SET_ERR_MSG_MOD(extack,
					   "Code and type matching only with ICMP and ICMPv6");
			netdev_err(priv->netdev,
				   "Code and type matching only with ICMP and ICMPv6\n");
			return -EINVAL;
		}
		if (match.mask->code || match.mask->type) {
			*match_level = MLX5_MATCH_L4;
			spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_3;
		}
	}
	return 0;
}

@@ -2979,7 +3040,8 @@ static bool actions_match_supported(struct mlx5e_priv *priv,
	actions = flow->attr->action;

	if (mlx5e_is_eswitch_flow(flow)) {
		if (flow->attr->esw_attr->split_count && ct_flow) {
		if (flow->attr->esw_attr->split_count && ct_flow &&
		    !MLX5_CAP_GEN(flow->attr->esw_attr->in_mdev, reg_c_preserve)) {
			/* All registers used by ct are cleared when using
			 * split rules.
			 */
@@ -3779,6 +3841,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
				return err;

			flow_flag_set(flow, CT);
			esw_attr->split_count = esw_attr->out_count;
			break;
		default:
			NL_SET_ERR_MSG_MOD(extack, "The offload action is not supported");
@@ -3841,11 +3904,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
			return -EOPNOTSUPP;
		}

		if (attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Mirroring goto chain rules isn't supported");
			return -EOPNOTSUPP;
		}
		attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
	}

Loading