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