Path: blob/main/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
39566 views
/*-1* SPDX-License-Identifier: BSD-2-Clause OR GPL-2.02*3* Copyright (c) 2004 Topspin Communications. All rights reserved.4*5* This software is available to you under a choice of one of two6* licenses. You may choose to be licensed under the terms of the GNU7* General Public License (GPL) Version 2, available from the file8* COPYING in the main directory of this source tree, or the9* OpenIB.org BSD license below:10*11* Redistribution and use in source and binary forms, with or12* without modification, are permitted provided that the following13* conditions are met:14*15* - Redistributions of source code must retain the above16* copyright notice, this list of conditions and the following17* disclaimer.18*19* - Redistributions in binary form must reproduce the above20* copyright notice, this list of conditions and the following21* disclaimer in the documentation and/or other materials22* provided with the distribution.23*24* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,25* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF26* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND27* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS28* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN29* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN30* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE31* SOFTWARE.32*/3334#include <sys/cdefs.h>35#include <linux/module.h>3637#include <linux/init.h>38#include <linux/slab.h>39#include <linux/seq_file.h>4041#include <asm/uaccess.h>4243#include "ipoib.h"4445static ssize_t show_parent(struct device *d, struct device_attribute *attr,46char *buf)47{48if_t dev = to_net_dev(d);49struct ipoib_dev_priv *priv = dev->if_softc;5051return sprintf(buf, "%s\n", priv->parent->name);52}53static DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);5455int ipoib_vlan_add(if_t pdev, unsigned short pkey)56{57struct ipoib_dev_priv *ppriv, *priv;58char intf_name[IFNAMSIZ];59int result;6061if (!capable(CAP_NET_ADMIN))62return -EPERM;6364ppriv = pdev->if_softc;6566rtnl_lock();67mutex_lock(&ppriv->vlan_mutex);6869/*70* First ensure this isn't a duplicate. We check the parent device and71* then all of the child interfaces to make sure the Pkey doesn't match.72*/73if (ppriv->pkey == pkey) {74result = -ENOTUNIQ;75priv = NULL;76goto err;77}7879list_for_each_entry(priv, &ppriv->child_intfs, list) {80if (priv->pkey == pkey) {81result = -ENOTUNIQ;82priv = NULL;83goto err;84}85}8687snprintf(intf_name, sizeof intf_name, "%s.%04x",88ppriv->dev->name, pkey);89priv = ipoib_intf_alloc(intf_name, ppriv->ca);90if (!priv) {91result = -ENOMEM;92goto err;93}9495priv->max_ib_mtu = ppriv->max_ib_mtu;96/* MTU will be reset when mcast join happens */97priv->dev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu);98priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu;99set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);100101result = ipoib_set_dev_features(priv, ppriv->ca);102if (result)103goto err;104105priv->pkey = pkey;106107memcpy(if_getlladdr(priv->dev), ppriv->dev->dev_addr, INFINIBAND_ALEN);108priv->broadcastaddr[8] = pkey >> 8;109priv->broadcastaddr[9] = pkey & 0xff;110111result = ipoib_dev_init(priv->dev, ppriv->ca, ppriv->port);112if (result < 0) {113ipoib_warn(ppriv, "failed to initialize subinterface: "114"device %s, port %d",115ppriv->ca->name, ppriv->port);116goto err;117}118119result = register_netdevice(priv->dev);120if (result) {121ipoib_warn(priv, "failed to initialize; error %i", result);122goto register_failed;123}124125priv->parent = ppriv->dev;126127ipoib_create_debug_files(priv->dev);128129if (ipoib_cm_add_mode_attr(priv->dev))130goto sysfs_failed;131if (ipoib_add_pkey_attr(priv->dev))132goto sysfs_failed;133if (ipoib_add_umcast_attr(priv->dev))134goto sysfs_failed;135136if (device_create_file(&priv->dev->dev, &dev_attr_parent))137goto sysfs_failed;138139list_add_tail(&priv->list, &ppriv->child_intfs);140141mutex_unlock(&ppriv->vlan_mutex);142rtnl_unlock();143144return 0;145146sysfs_failed:147ipoib_delete_debug_files(priv->dev);148unregister_netdevice(priv->dev);149150register_failed:151ipoib_dev_cleanup(priv->dev);152153err:154mutex_unlock(&ppriv->vlan_mutex);155rtnl_unlock();156if (priv)157free_netdev(priv->dev);158159return result;160}161162int ipoib_vlan_delete(if_t pdev, unsigned short pkey)163{164struct ipoib_dev_priv *ppriv, *priv, *tpriv;165if_t dev = NULL;166167if (!capable(CAP_NET_ADMIN))168return -EPERM;169170ppriv = pdev->if_softc;171172rtnl_lock();173mutex_lock(&ppriv->vlan_mutex);174list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {175if (priv->pkey == pkey) {176unregister_netdevice(priv->dev);177ipoib_dev_cleanup(priv->dev);178list_del(&priv->list);179dev = priv->dev;180break;181}182}183mutex_unlock(&ppriv->vlan_mutex);184rtnl_unlock();185186if (dev) {187free_netdev(dev);188return 0;189}190191return -ENODEV;192}193194195