brintos

brintos / linux-shallow public Read only

0
0
Text · 8.9 KiB · f2fb2d8 Raw
367 lines · c
1/*2 * Copyright (c) 2015, Mellanox Technologies inc.  All rights reserved.3 *4 * This software is available to you under a choice of one of two5 * licenses.  You may choose to be licensed under the terms of the GNU6 * General Public License (GPL) Version 2, available from the file7 * COPYING in the main directory of this source tree, or the8 * OpenIB.org BSD license below:9 *10 *     Redistribution and use in source and binary forms, with or11 *     without modification, are permitted provided that the following12 *     conditions are met:13 *14 *      - Redistributions of source code must retain the above15 *        copyright notice, this list of conditions and the following16 *        disclaimer.17 *18 *      - Redistributions in binary form must reproduce the above19 *        copyright notice, this list of conditions and the following20 *        disclaimer in the documentation and/or other materials21 *        provided with the distribution.22 *23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE30 * SOFTWARE.31 */32 33#include <linux/configfs.h>34#include <rdma/ib_verbs.h>35#include <rdma/rdma_cm.h>36 37#include "core_priv.h"38#include "cma_priv.h"39 40struct cma_device;41 42struct cma_dev_group;43 44struct cma_dev_port_group {45	u32			port_num;46	struct cma_dev_group	*cma_dev_group;47	struct config_group	group;48};49 50struct cma_dev_group {51	char				name[IB_DEVICE_NAME_MAX];52	struct config_group		device_group;53	struct config_group		ports_group;54	struct cma_dev_port_group	*ports;55};56 57static struct cma_dev_port_group *to_dev_port_group(struct config_item *item)58{59	struct config_group *group;60 61	if (!item)62		return NULL;63 64	group = container_of(item, struct config_group, cg_item);65	return container_of(group, struct cma_dev_port_group, group);66}67 68static bool filter_by_name(struct ib_device *ib_dev, void *cookie)69{70	return !strcmp(dev_name(&ib_dev->dev), cookie);71}72 73static int cma_configfs_params_get(struct config_item *item,74				   struct cma_device **pcma_dev,75				   struct cma_dev_port_group **pgroup)76{77	struct cma_dev_port_group *group = to_dev_port_group(item);78	struct cma_device *cma_dev;79 80	if (!group)81		return -ENODEV;82 83	cma_dev = cma_enum_devices_by_ibdev(filter_by_name,84					    group->cma_dev_group->name);85	if (!cma_dev)86		return -ENODEV;87 88	*pcma_dev = cma_dev;89	*pgroup = group;90 91	return 0;92}93 94static void cma_configfs_params_put(struct cma_device *cma_dev)95{96	cma_dev_put(cma_dev);97}98 99static ssize_t default_roce_mode_show(struct config_item *item,100				      char *buf)101{102	struct cma_device *cma_dev;103	struct cma_dev_port_group *group;104	int gid_type;105	ssize_t ret;106 107	ret = cma_configfs_params_get(item, &cma_dev, &group);108	if (ret)109		return ret;110 111	gid_type = cma_get_default_gid_type(cma_dev, group->port_num);112	cma_configfs_params_put(cma_dev);113 114	if (gid_type < 0)115		return gid_type;116 117	return sysfs_emit(buf, "%s\n", ib_cache_gid_type_str(gid_type));118}119 120static ssize_t default_roce_mode_store(struct config_item *item,121				       const char *buf, size_t count)122{123	struct cma_device *cma_dev;124	struct cma_dev_port_group *group;125	int gid_type;126	ssize_t ret;127 128	ret = cma_configfs_params_get(item, &cma_dev, &group);129	if (ret)130		return ret;131 132	gid_type = ib_cache_gid_parse_type_str(buf);133	if (gid_type < 0) {134		cma_configfs_params_put(cma_dev);135		return -EINVAL;136	}137 138	ret = cma_set_default_gid_type(cma_dev, group->port_num, gid_type);139 140	cma_configfs_params_put(cma_dev);141 142	return !ret ? strnlen(buf, count) : ret;143}144 145CONFIGFS_ATTR(, default_roce_mode);146 147static ssize_t default_roce_tos_show(struct config_item *item, char *buf)148{149	struct cma_device *cma_dev;150	struct cma_dev_port_group *group;151	ssize_t ret;152	u8 tos;153 154	ret = cma_configfs_params_get(item, &cma_dev, &group);155	if (ret)156		return ret;157 158	tos = cma_get_default_roce_tos(cma_dev, group->port_num);159	cma_configfs_params_put(cma_dev);160 161	return sysfs_emit(buf, "%u\n", tos);162}163 164static ssize_t default_roce_tos_store(struct config_item *item,165				      const char *buf, size_t count)166{167	struct cma_device *cma_dev;168	struct cma_dev_port_group *group;169	ssize_t ret;170	u8 tos;171 172	ret = kstrtou8(buf, 0, &tos);173	if (ret)174		return ret;175 176	ret = cma_configfs_params_get(item, &cma_dev, &group);177	if (ret)178		return ret;179 180	ret = cma_set_default_roce_tos(cma_dev, group->port_num, tos);181	cma_configfs_params_put(cma_dev);182 183	return ret ? ret : strnlen(buf, count);184}185 186CONFIGFS_ATTR(, default_roce_tos);187 188static struct configfs_attribute *cma_configfs_attributes[] = {189	&attr_default_roce_mode,190	&attr_default_roce_tos,191	NULL,192};193 194static const struct config_item_type cma_port_group_type = {195	.ct_attrs	= cma_configfs_attributes,196	.ct_owner	= THIS_MODULE197};198 199static int make_cma_ports(struct cma_dev_group *cma_dev_group,200			  struct cma_device *cma_dev)201{202	struct cma_dev_port_group *ports;203	struct ib_device *ibdev;204	u32 ports_num;205	u32 i;206 207	ibdev = cma_get_ib_dev(cma_dev);208 209	if (!ibdev)210		return -ENODEV;211 212	ports_num = ibdev->phys_port_cnt;213	ports = kcalloc(ports_num, sizeof(*cma_dev_group->ports),214			GFP_KERNEL);215 216	if (!ports)217		return -ENOMEM;218 219	for (i = 0; i < ports_num; i++) {220		char port_str[11];221 222		ports[i].port_num = i + 1;223		snprintf(port_str, sizeof(port_str), "%u", i + 1);224		ports[i].cma_dev_group = cma_dev_group;225		config_group_init_type_name(&ports[i].group,226					    port_str,227					    &cma_port_group_type);228		configfs_add_default_group(&ports[i].group,229				&cma_dev_group->ports_group);230 231	}232	cma_dev_group->ports = ports;233	return 0;234}235 236static void release_cma_dev(struct config_item  *item)237{238	struct config_group *group = container_of(item, struct config_group,239						  cg_item);240	struct cma_dev_group *cma_dev_group = container_of(group,241							   struct cma_dev_group,242							   device_group);243 244	kfree(cma_dev_group);245};246 247static void release_cma_ports_group(struct config_item  *item)248{249	struct config_group *group = container_of(item, struct config_group,250						  cg_item);251	struct cma_dev_group *cma_dev_group = container_of(group,252							   struct cma_dev_group,253							   ports_group);254 255	kfree(cma_dev_group->ports);256	cma_dev_group->ports = NULL;257};258 259static struct configfs_item_operations cma_ports_item_ops = {260	.release = release_cma_ports_group261};262 263static const struct config_item_type cma_ports_group_type = {264	.ct_item_ops	= &cma_ports_item_ops,265	.ct_owner	= THIS_MODULE266};267 268static struct configfs_item_operations cma_device_item_ops = {269	.release = release_cma_dev270};271 272static const struct config_item_type cma_device_group_type = {273	.ct_item_ops	= &cma_device_item_ops,274	.ct_owner	= THIS_MODULE275};276 277static struct config_group *make_cma_dev(struct config_group *group,278					 const char *name)279{280	int err = -ENODEV;281	struct cma_device *cma_dev = cma_enum_devices_by_ibdev(filter_by_name,282							       (void *)name);283	struct cma_dev_group *cma_dev_group = NULL;284 285	if (!cma_dev)286		goto fail;287 288	cma_dev_group = kzalloc(sizeof(*cma_dev_group), GFP_KERNEL);289 290	if (!cma_dev_group) {291		err = -ENOMEM;292		goto fail;293	}294 295	strscpy(cma_dev_group->name, name, sizeof(cma_dev_group->name));296 297	config_group_init_type_name(&cma_dev_group->ports_group, "ports",298				    &cma_ports_group_type);299 300	err = make_cma_ports(cma_dev_group, cma_dev);301	if (err)302		goto fail;303 304	config_group_init_type_name(&cma_dev_group->device_group, name,305				    &cma_device_group_type);306	configfs_add_default_group(&cma_dev_group->ports_group,307			&cma_dev_group->device_group);308 309	cma_dev_put(cma_dev);310	return &cma_dev_group->device_group;311 312fail:313	if (cma_dev)314		cma_dev_put(cma_dev);315	kfree(cma_dev_group);316	return ERR_PTR(err);317}318 319static void drop_cma_dev(struct config_group *cgroup, struct config_item *item)320{321	struct config_group *group =322		container_of(item, struct config_group, cg_item);323	struct cma_dev_group *cma_dev_group =324		container_of(group, struct cma_dev_group, device_group);325 326	configfs_remove_default_groups(&cma_dev_group->ports_group);327	configfs_remove_default_groups(&cma_dev_group->device_group);328	config_item_put(item);329}330 331static struct configfs_group_operations cma_subsys_group_ops = {332	.make_group	= make_cma_dev,333	.drop_item	= drop_cma_dev,334};335 336static const struct config_item_type cma_subsys_type = {337	.ct_group_ops	= &cma_subsys_group_ops,338	.ct_owner	= THIS_MODULE,339};340 341static struct configfs_subsystem cma_subsys = {342	.su_group	= {343		.cg_item	= {344			.ci_namebuf	= "rdma_cm",345			.ci_type	= &cma_subsys_type,346		},347	},348};349 350int __init cma_configfs_init(void)351{352	int ret;353 354	config_group_init(&cma_subsys.su_group);355	mutex_init(&cma_subsys.su_mutex);356	ret = configfs_register_subsystem(&cma_subsys);357	if (ret)358		mutex_destroy(&cma_subsys.su_mutex);359	return ret;360}361 362void __exit cma_configfs_exit(void)363{364	configfs_unregister_subsystem(&cma_subsys);365	mutex_destroy(&cma_subsys.su_mutex);366}367