brintos

brintos / linux-shallow public Read only

0
0
Text · 4.0 KiB · a42f6cd Raw
175 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB2/* Copyright (c) 2019 Mellanox Technologies */3 4#include <linux/mlx5/vport.h>5#include <rdma/ib_verbs.h>6#include <net/addrconf.h>7 8#include "lib/mlx5.h"9#include "eswitch.h"10#include "fs_core.h"11#include "rdma.h"12 13static void mlx5_rdma_disable_roce_steering(struct mlx5_core_dev *dev)14{15	struct mlx5_core_roce *roce = &dev->priv.roce;16 17	mlx5_del_flow_rules(roce->allow_rule);18	mlx5_destroy_flow_group(roce->fg);19	mlx5_destroy_flow_table(roce->ft);20}21 22static int mlx5_rdma_enable_roce_steering(struct mlx5_core_dev *dev)23{24	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);25	struct mlx5_core_roce *roce = &dev->priv.roce;26	struct mlx5_flow_handle *flow_rule = NULL;27	struct mlx5_flow_table_attr ft_attr = {};28	struct mlx5_flow_namespace *ns = NULL;29	struct mlx5_flow_act flow_act = {};30	struct mlx5_flow_spec *spec;31	struct mlx5_flow_table *ft;32	struct mlx5_flow_group *fg;33	struct mlx5_eswitch *esw;34	u32 *flow_group_in;35	int err;36 37	if (!(MLX5_CAP_FLOWTABLE_RDMA_RX(dev, ft_support) &&38	      MLX5_CAP_FLOWTABLE_RDMA_RX(dev, table_miss_action_domain)))39		return -EOPNOTSUPP;40 41	flow_group_in = kvzalloc(inlen, GFP_KERNEL);42	if (!flow_group_in)43		return -ENOMEM;44	spec = kvzalloc(sizeof(*spec), GFP_KERNEL);45	if (!spec) {46		kvfree(flow_group_in);47		return -ENOMEM;48	}49 50	ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL);51	if (!ns) {52		mlx5_core_err(dev, "Failed to get RDMA RX namespace");53		err = -EOPNOTSUPP;54		goto free;55	}56 57	ft_attr.max_fte = 1;58	ft = mlx5_create_flow_table(ns, &ft_attr);59	if (IS_ERR(ft)) {60		mlx5_core_err(dev, "Failed to create RDMA RX flow table");61		err = PTR_ERR(ft);62		goto free;63	}64 65	esw = dev->priv.eswitch;66	mlx5_esw_set_flow_group_source_port(esw, flow_group_in, 0);67 68	fg = mlx5_create_flow_group(ft, flow_group_in);69	if (IS_ERR(fg)) {70		err = PTR_ERR(fg);71		mlx5_core_err(dev, "Failed to create RDMA RX flow group err(%d)\n", err);72		goto destroy_flow_table;73	}74 75	mlx5_esw_set_spec_source_port(esw, esw->manager_vport, spec);76 77	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;78	flow_rule = mlx5_add_flow_rules(ft, spec, &flow_act, NULL, 0);79	if (IS_ERR(flow_rule)) {80		err = PTR_ERR(flow_rule);81		mlx5_core_err(dev, "Failed to add RoCE allow rule, err=%d\n",82			      err);83		goto destroy_flow_group;84	}85 86	kvfree(spec);87	kvfree(flow_group_in);88	roce->ft = ft;89	roce->fg = fg;90	roce->allow_rule = flow_rule;91 92	return 0;93 94destroy_flow_group:95	mlx5_destroy_flow_group(fg);96destroy_flow_table:97	mlx5_destroy_flow_table(ft);98free:99	kvfree(spec);100	kvfree(flow_group_in);101	return err;102}103 104static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev)105{106	mlx5_core_roce_gid_set(dev, 0, MLX5_ROCE_VERSION_2, 0,107			       NULL, NULL, false, 0, 1);108}109 110static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid)111{112	u8 hw_id[ETH_ALEN];113 114	mlx5_query_mac_address(dev, hw_id);115	gid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);116	addrconf_addr_eui48(&gid->raw[8], hw_id);117}118 119static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev)120{121	union ib_gid gid;122	u8 mac[ETH_ALEN];123 124	mlx5_rdma_make_default_gid(dev, &gid);125	return mlx5_core_roce_gid_set(dev, 0,126				      MLX5_ROCE_VERSION_2,127				      0, gid.raw, mac,128				      false, 0, 1);129}130 131void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev)132{133	struct mlx5_core_roce *roce = &dev->priv.roce;134 135	if (!roce->ft)136		return;137 138	mlx5_rdma_disable_roce_steering(dev);139	mlx5_rdma_del_roce_addr(dev);140	mlx5_nic_vport_disable_roce(dev);141}142 143void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)144{145	int err;146 147	if (!MLX5_CAP_GEN(dev, roce))148		return;149 150	err = mlx5_nic_vport_enable_roce(dev);151	if (err) {152		mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);153		return;154	}155 156	err = mlx5_rdma_add_roce_addr(dev);157	if (err) {158		mlx5_core_err(dev, "Failed to add RoCE address: %d\n", err);159		goto disable_roce;160	}161 162	err = mlx5_rdma_enable_roce_steering(dev);163	if (err) {164		mlx5_core_err(dev, "Failed to enable RoCE steering: %d\n", err);165		goto del_roce_addr;166	}167 168	return;169 170del_roce_addr:171	mlx5_rdma_del_roce_addr(dev);172disable_roce:173	mlx5_nic_vport_disable_roce(dev);174}175