// SPDX-License-Identifier: GPL-2.0
/* net/atm/resources.c - Statically allocated resources */

/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */

/* Fixes
 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 * 2002/01 - don't free the whole struct sock on sk->destruct time,
 * 	     use the default destruct function initialized by sock_init_data */

#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__

#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/kernel.h> /* for barrier */
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/capability.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/slab.h>

#include <net/sock.h>	 /* for struct sock */

#include "common.h"
#include "resources.h"
#include "addr.h"


LIST_HEAD(atm_devs);
DEFINE_MUTEX(atm_dev_mutex);

static struct atm_dev *__alloc_atm_dev(const char *type)
{
	struct atm_dev *dev;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return NULL;
	dev->type = type;
	dev->signal = ATM_PHY_SIG_UNKNOWN;
	dev->link_rate = ATM_OC3_PCR;
	spin_lock_init(&dev->lock);
	INIT_LIST_HEAD(&dev->local);
	INIT_LIST_HEAD(&dev->lecs);

	return dev;
}

static struct atm_dev *__atm_dev_lookup(int number)
{
	struct atm_dev *dev;
	struct list_head *p;

	list_for_each(p, &atm_devs) {
		dev = list_entry(p, struct atm_dev, dev_list);
		if (dev->number == number) {
			atm_dev_hold(dev);
			return dev;
		}
	}
	return NULL;
}

struct atm_dev *atm_dev_lookup(int number)
{
	struct atm_dev *dev;

	mutex_lock(&atm_dev_mutex);
	dev = __atm_dev_lookup(number);
	mutex_unlock(&atm_dev_mutex);
	return dev;
}
EXPORT_SYMBOL(atm_dev_lookup);

struct atm_dev *atm_dev_register(const char *type, struct device *parent,
				 const struct atmdev_ops *ops, int number,
				 unsigned long *flags)
{
	struct atm_dev *dev, *inuse;

	dev = __alloc_atm_dev(type);
	if (!dev) {
		pr_err("no space for dev %s\n", type);
		return NULL;
	}
	mutex_lock(&atm_dev_mutex);
	if (number != -1) {
		inuse = __atm_dev_lookup(number);
		if (inuse) {
			atm_dev_put(inuse);
			mutex_unlock(&atm_dev_mutex);
			kfree(dev);
			return NULL;
		}
		dev->number = number;
	} else {
		dev->number = 0;
		while ((inuse = __atm_dev_lookup(dev->number))) {
			atm_dev_put(inuse);
			dev->number++;
		}
	}

	dev->ops = ops;
	if (flags)
		dev->flags = *flags;
	else
		memset(&dev->flags, 0, sizeof(dev->flags));
	memset(&dev->stats, 0, sizeof(dev->stats));
	refcount_set(&dev->refcnt, 1);

	if (atm_proc_dev_register(dev) < 0) {
		pr_err("atm_proc_dev_register failed for dev %s\n", type);
		goto out_fail;
	}

	if (atm_register_sysfs(dev, parent) < 0) {
		pr_err("atm_register_sysfs failed for dev %s\n", type);
		atm_proc_dev_deregister(dev);
		goto out_fail;
	}

	list_add_tail(&dev->dev_list, &atm_devs);

out:
	mutex_unlock(&atm_dev_mutex);
	return dev;

out_fail:
	kfree(dev);
	dev = NULL;
	goto out;
}
EXPORT_SYMBOL(atm_dev_register);

void atm_dev_deregister(struct atm_dev *dev)
{
	BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags));
	set_bit(ATM_DF_REMOVED, &dev->flags);

	/*
	 * if we remove current device from atm_devs list, new device
	 * with same number can appear, such we need deregister proc,
	 * release async all vccs and remove them from vccs list too
	 */
	mutex_lock(&atm_dev_mutex);
	list_del(&dev->dev_list);
	mutex_unlock(&atm_dev_mutex);

	atm_dev_release_vccs(dev);
	atm_unregister_sysfs(dev);
	atm_proc_dev_deregister(dev);

	atm_dev_put(dev);
}
EXPORT_SYMBOL(atm_dev_deregister);

static void copy_aal_stats(struct k_atm_aal_stats *from,
    struct atm_aal_stats *to)
{
#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
	__AAL_STAT_ITEMS
#undef __HANDLE_ITEM
}

static void subtract_aal_stats(struct k_atm_aal_stats *from,
    struct atm_aal_stats *to)
{
#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
	__AAL_STAT_ITEMS
#undef __HANDLE_ITEM
}

static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats __user *arg,
		       int zero)
{
	struct atm_dev_stats tmp;
	int error = 0;

	copy_aal_stats(&dev->stats.aal0, &tmp.aal0);
	copy_aal_stats(&dev->stats.aal34, &tmp.aal34);
	copy_aal_stats(&dev->stats.aal5, &tmp.aal5);
	if (arg)
		error = copy_to_user(arg, &tmp, sizeof(tmp));
	if (zero && !error) {
		subtract_aal_stats(&dev->stats.aal0, &tmp.aal0);
		subtract_aal_stats(&dev->stats.aal34, &tmp.aal34);
		subtract_aal_stats(&dev->stats.aal5, &tmp.aal5);
	}
	return error ? -EFAULT : 0;
}

int atm_dev_ioctl(unsigned int cmd, void __user *arg, int compat)
{
	void __user *buf;
	int error, len, number, size = 0;
	struct atm_dev *dev;
	struct list_head *p;
	int *tmp_buf, *tmp_p;
	int __user *sioc_len;
	int __user *iobuf_len;

	switch (cmd) {
	case ATM_GETNAMES:
		if (IS_ENABLED(CONFIG_COMPAT) && compat) {
#ifdef CONFIG_COMPAT
			struct compat_atm_iobuf __user *ciobuf = arg;
			compat_uptr_t cbuf;
			iobuf_len = &ciobuf->length;
			if (get_user(cbuf, &ciobuf->buffer))
				return -EFAULT;
			buf = compat_ptr(cbuf);
#endif
		} else {
			struct atm_iobuf __user *iobuf = arg;
			iobuf_len = &iobuf->length;
			if (get_user(buf, &iobuf->buffer))
				return -EFAULT;
		}
		if (get_user(len, iobuf_len))
			return -EFAULT;
		mutex_lock(&atm_dev_mutex);
		list_for_each(p, &atm_devs)
			size += sizeof(int);
		if (size > len) {
			mutex_unlock(&atm_dev_mutex);
			return -E2BIG;
		}
		tmp_buf = kmalloc(size, GFP_ATOMIC);
		if (!tmp_buf) {
			mutex_unlock(&atm_dev_mutex);
			return -ENOMEM;
		}
		tmp_p = tmp_buf;
		list_for_each(p, &atm_devs) {
			dev = list_entry(p, struct atm_dev, dev_list);
			*tmp_p++ = dev->number;
		}
		mutex_unlock(&atm_dev_mutex);
		error = ((copy_to_user(buf, tmp_buf, size)) ||
			 put_user(size, iobuf_len))
			? -EFAULT : 0;
		kfree(tmp_buf);
		return error;
	default:
		break;
	}

	if (IS_ENABLED(CONFIG_COMPAT) && compat) {
#ifdef CONFIG_COMPAT
		struct compat_atmif_sioc __user *csioc = arg;
		compat_uptr_t carg;

		sioc_len = &csioc->length;
		if (get_user(carg, &csioc->arg))
			return -EFAULT;
		buf = compat_ptr(carg);

		if (get_user(len, &csioc->length))
			return -EFAULT;
		if (get_user(number, &csioc->number))
			return -EFAULT;
#endif
	} else {
		struct atmif_sioc __user *sioc = arg;

		sioc_len = &sioc->length;
		if (get_user(buf, &sioc->arg))
			return -EFAULT;
		if (get_user(len, &sioc->length))
			return -EFAULT;
		if (get_user(number, &sioc->number))
			return -EFAULT;
	}

	dev = try_then_request_module(atm_dev_lookup(number), "atm-device-%d",
				      number);
	if (!dev)
		return -ENODEV;

	switch (cmd) {
	case ATM_GETTYPE:
		size = strlen(dev->type) + 1;
		if (copy_to_user(buf, dev->type, size)) {
			error = -EFAULT;
			goto done;
		}
		break;
	case ATM_GETESI:
		size = ESI_LEN;
		if (copy_to_user(buf, dev->esi, size)) {
			error = -EFAULT;
			goto done;
		}
		break;
	case ATM_SETESI:
	{
		int i;

		for (i = 0; i < ESI_LEN; i++)
			if (dev->esi[i]) {
				error = -EEXIST;
				goto done;
			}
	}
	/* fall through */
	case ATM_SETESIF:
	{
		unsigned char esi[ESI_LEN];

		if (!capable(CAP_NET_ADMIN)) {
			error = -EPERM;
			goto done;
		}
		if (copy_from_user(esi, buf, ESI_LEN)) {
			error = -EFAULT;
			goto done;
		}
		memcpy(dev->esi, esi, ESI_LEN);
		error =  ESI_LEN;
		goto done;
	}
	case ATM_GETSTATZ:
		if (!capable(CAP_NET_ADMIN)) {
			error = -EPERM;
			goto done;
		}
		/* fall through */
	case ATM_GETSTAT:
		size = sizeof(struct atm_dev_stats);
		error = fetch_stats(dev, buf, cmd == ATM_GETSTATZ);
		if (error)
			goto done;
		break;
	case ATM_GETCIRANGE:
		size = sizeof(struct atm_cirange);
		if (copy_to_user(buf, &dev->ci_range, size)) {
			error = -EFAULT;
			goto done;
		}
		break;
	case ATM_GETLINKRATE:
		size = sizeof(int);
		if (copy_to_user(buf, &dev->link_rate, size)) {
			error = -EFAULT;
			goto done;
		}
		break;
	case ATM_RSTADDR:
		if (!capable(CAP_NET_ADMIN)) {
			error = -EPERM;
			goto done;
		}
		atm_reset_addr(dev, ATM_ADDR_LOCAL);
		break;
	case ATM_ADDADDR:
	case ATM_DELADDR:
	case ATM_ADDLECSADDR:
	case ATM_DELLECSADDR:
	{
		struct sockaddr_atmsvc addr;

		if (!capable(CAP_NET_ADMIN)) {
			error = -EPERM;
			goto done;
		}

		if (copy_from_user(&addr, buf, sizeof(addr))) {
			error = -EFAULT;
			goto done;
		}
		if (cmd == ATM_ADDADDR || cmd == ATM_ADDLECSADDR)
			error = atm_add_addr(dev, &addr,
					     (cmd == ATM_ADDADDR ?
					      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
		else
			error = atm_del_addr(dev, &addr,
					     (cmd == ATM_DELADDR ?
					      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
		goto done;
	}
	case ATM_GETADDR:
	case ATM_GETLECSADDR:
		error = atm_get_addr(dev, buf, len,
				     (cmd == ATM_GETADDR ?
				      ATM_ADDR_LOCAL : ATM_ADDR_LECS));
		if (error < 0)
			goto done;
		size = error;
		/* may return 0, but later on size == 0 means "don't
		   write the length" */
		error = put_user(size, sioc_len) ? -EFAULT : 0;
		goto done;
	case ATM_SETLOOP:
		if (__ATM_LM_XTRMT((int) (unsigned long) buf) &&
		    __ATM_LM_XTLOC((int) (unsigned long) buf) >
		    __ATM_LM_XTRMT((int) (unsigned long) buf)) {
			error = -EINVAL;
			goto done;
		}
		/* fall through */
	case ATM_SETCIRANGE:
	case SONET_GETSTATZ:
	case SONET_SETDIAG:
	case SONET_CLRDIAG:
	case SONET_SETFRAMING:
		if (!capable(CAP_NET_ADMIN)) {
			error = -EPERM;
			goto done;
		}
		/* fall through */
	default:
		if (IS_ENABLED(CONFIG_COMPAT) && compat) {
#ifdef CONFIG_COMPAT
			if (!dev->ops->compat_ioctl) {
				error = -EINVAL;
				goto done;
			}
			size = dev->ops->compat_ioctl(dev, cmd, buf);
#endif
		} else {
			if (!dev->ops->ioctl) {
				error = -EINVAL;
				goto done;
			}
			size = dev->ops->ioctl(dev, cmd, buf);
		}
		if (size < 0) {
			error = (size == -ENOIOCTLCMD ? -ENOTTY : size);
			goto done;
		}
	}

	if (size)
		error = put_user(size, sioc_len) ? -EFAULT : 0;
	else
		error = 0;
done:
	atm_dev_put(dev);
	return error;
}

void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
{
	mutex_lock(&atm_dev_mutex);
	return seq_list_start_head(&atm_devs, *pos);
}

void atm_dev_seq_stop(struct seq_file *seq, void *v)
{
	mutex_unlock(&atm_dev_mutex);
}

void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	return seq_list_next(v, &atm_devs, pos);
}
