// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2019 Mellanox Technologies */

#include <linux/mlx5/vport.h>
#include <rdma/ib_verbs.h>
#include <net/addrconf.h>

#include "lib/mlx5.h"
#include "eswitch.h"
#include "fs_core.h"
#include "rdma.h"

static void mlx5_rdma_disable_roce_steering(struct mlx5_core_dev *dev)
{
	struct mlx5_core_roce *roce = &dev->priv.roce;

	if (!roce->ft)
		return;

	mlx5_del_flow_rules(roce->allow_rule);
	mlx5_destroy_flow_group(roce->fg);
	mlx5_destroy_flow_table(roce->ft);
}

static int mlx5_rdma_enable_roce_steering(struct mlx5_core_dev *dev)
{
	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
	struct mlx5_core_roce *roce = &dev->priv.roce;
	struct mlx5_flow_handle *flow_rule = NULL;
	struct mlx5_flow_table_attr ft_attr = {};
	struct mlx5_flow_namespace *ns = NULL;
	struct mlx5_flow_act flow_act = {};
	struct mlx5_flow_spec *spec;
	struct mlx5_flow_table *ft;
	struct mlx5_flow_group *fg;
	void *match_criteria;
	u32 *flow_group_in;
	void *misc;
	int err;

	if (!(MLX5_CAP_FLOWTABLE_RDMA_RX(dev, ft_support) &&
	      MLX5_CAP_FLOWTABLE_RDMA_RX(dev, table_miss_action_domain)))
		return -EOPNOTSUPP;

	flow_group_in = kvzalloc(inlen, GFP_KERNEL);
	if (!flow_group_in)
		return -ENOMEM;
	spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
	if (!spec) {
		kvfree(flow_group_in);
		return -ENOMEM;
	}

	ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_RDMA_RX);
	if (!ns) {
		mlx5_core_err(dev, "Failed to get RDMA RX namespace");
		err = -EOPNOTSUPP;
		goto free;
	}

	ft_attr.max_fte = 1;
	ft = mlx5_create_flow_table(ns, &ft_attr);
	if (IS_ERR(ft)) {
		mlx5_core_err(dev, "Failed to create RDMA RX flow table");
		err = PTR_ERR(ft);
		goto free;
	}

	MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable,
		 MLX5_MATCH_MISC_PARAMETERS);
	match_criteria = MLX5_ADDR_OF(create_flow_group_in, flow_group_in,
				      match_criteria);
	MLX5_SET_TO_ONES(fte_match_param, match_criteria,
			 misc_parameters.source_port);

	fg = mlx5_create_flow_group(ft, flow_group_in);
	if (IS_ERR(fg)) {
		err = PTR_ERR(fg);
		mlx5_core_err(dev, "Failed to create RDMA RX flow group err(%d)\n", err);
		goto destroy_flow_table;
	}

	spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS;
	misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
			    misc_parameters);
	MLX5_SET(fte_match_set_misc, misc, source_port,
		 dev->priv.eswitch->manager_vport);
	misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
			    misc_parameters);
	MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);

	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
	flow_rule = mlx5_add_flow_rules(ft, spec, &flow_act, NULL, 0);
	if (IS_ERR(flow_rule)) {
		err = PTR_ERR(flow_rule);
		mlx5_core_err(dev, "Failed to add RoCE allow rule, err=%d\n",
			      err);
		goto destroy_flow_group;
	}

	kvfree(spec);
	kvfree(flow_group_in);
	roce->ft = ft;
	roce->fg = fg;
	roce->allow_rule = flow_rule;

	return 0;

destroy_flow_group:
	mlx5_destroy_flow_group(fg);
destroy_flow_table:
	mlx5_destroy_flow_table(ft);
free:
	kvfree(spec);
	kvfree(flow_group_in);
	return err;
}

static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev)
{
	mlx5_core_roce_gid_set(dev, 0, 0, 0,
			       NULL, NULL, false, 0, 0);
}

static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid)
{
	u8 hw_id[ETH_ALEN];

	mlx5_query_mac_address(dev, hw_id);
	gid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
	addrconf_addr_eui48(&gid->raw[8], hw_id);
}

static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev)
{
	union ib_gid gid;
	u8 mac[ETH_ALEN];

	mlx5_rdma_make_default_gid(dev, &gid);
	return mlx5_core_roce_gid_set(dev, 0,
				      MLX5_ROCE_VERSION_1,
				      0, gid.raw, mac,
				      false, 0, 1);
}

void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev)
{
	mlx5_rdma_disable_roce_steering(dev);
	mlx5_rdma_del_roce_addr(dev);
	mlx5_nic_vport_disable_roce(dev);
}

void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
{
	int err;

	err = mlx5_nic_vport_enable_roce(dev);
	if (err) {
		mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
		return;
	}

	err = mlx5_rdma_add_roce_addr(dev);
	if (err) {
		mlx5_core_err(dev, "Failed to add RoCE address: %d\n", err);
		goto disable_roce;
	}

	err = mlx5_rdma_enable_roce_steering(dev);
	if (err) {
		mlx5_core_err(dev, "Failed to enable RoCE steering: %d\n", err);
		goto del_roce_addr;
	}

	return;

del_roce_addr:
	mlx5_rdma_del_roce_addr(dev);
disable_roce:
	mlx5_nic_vport_disable_roce(dev);
	return;
}
