// 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;

	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;
	struct mlx5_eswitch *esw;
	u32 *flow_group_in;
	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_KERNEL);
	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;
	}

	esw = dev->priv.eswitch;
	mlx5_esw_set_flow_group_source_port(esw, flow_group_in, 0);

	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;
	}

	mlx5_esw_set_spec_source_port(esw, esw->manager_vport, spec);

	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, MLX5_ROCE_VERSION_2, 0,
			       NULL, NULL, false, 0, 1);
}

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_2,
				      0, gid.raw, mac,
				      false, 0, 1);
}

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

	if (!roce->ft)
		return;

	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;

	if (!MLX5_CAP_GEN(dev, roce))
		return;

	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);
}
