// SPDX-License-Identifier: GPL-2.0-only
/*
 * adummy.c: a dummy ATM driver
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <linux/uaccess.h>

#include <linux/atmdev.h>
#include <linux/atm.h>
#include <linux/sonet.h>

/* version definition */

#define DRV_VERSION "1.0"

#define DEV_LABEL "adummy"

#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)

struct adummy_dev {
	struct atm_dev *atm_dev;

	struct list_head entry;
};

/* globals */

static LIST_HEAD(adummy_devs);

static ssize_t __set_signal(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t len)
{
	struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
	int signal;

	if (sscanf(buf, "%d", &signal) == 1) {

		if (signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND)
			signal = ATM_PHY_SIG_UNKNOWN;

		atm_dev_signal_change(atm_dev, signal);
		return 1;
	}
	return -EINVAL;
}

static ssize_t __show_signal(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
	return sprintf(buf, "%d\n", atm_dev->signal);
}
static DEVICE_ATTR(signal, 0644, __show_signal, __set_signal);

static struct attribute *adummy_attrs[] = {
	&dev_attr_signal.attr,
	NULL
};

static const struct attribute_group adummy_group_attrs = {
	.name = NULL, /* We want them in dev's root folder */
	.attrs = adummy_attrs
};

static int __init
adummy_start(struct atm_dev *dev)
{
	dev->ci_range.vpi_bits = 4;
	dev->ci_range.vci_bits = 12;

	return 0;
}

static int
adummy_open(struct atm_vcc *vcc)
{
	short vpi = vcc->vpi;
	int vci = vcc->vci;

	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
		return 0;

	set_bit(ATM_VF_ADDR, &vcc->flags);
	set_bit(ATM_VF_READY, &vcc->flags);

	return 0;
}

static void
adummy_close(struct atm_vcc *vcc)
{
	clear_bit(ATM_VF_READY, &vcc->flags);
	clear_bit(ATM_VF_ADDR, &vcc->flags);
}

static int
adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
{
	if (vcc->pop)
		vcc->pop(vcc, skb);
	else
		dev_kfree_skb_any(skb);
	atomic_inc(&vcc->stats->tx);

	return 0;
}

static int
adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
{
	int left = *pos;

	if (!left--)
		return sprintf(page, "version %s\n", DRV_VERSION);

	return 0;
}

static const struct atmdev_ops adummy_ops =
{
	.open =		adummy_open,
	.close =	adummy_close,	
	.send =		adummy_send,
	.proc_read =	adummy_proc_read,
	.owner =	THIS_MODULE
};

static int __init adummy_init(void)
{
	struct atm_dev *atm_dev;
	struct adummy_dev *adummy_dev;
	int err = 0;

	printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);

	adummy_dev = kzalloc(sizeof(struct adummy_dev),
						   GFP_KERNEL);
	if (!adummy_dev) {
		printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
		err = -ENOMEM;
		goto out;
	}
	atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
	if (!atm_dev) {
		printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
		err = -ENODEV;
		goto out_kfree;
	}

	adummy_dev->atm_dev = atm_dev;
	atm_dev->dev_data = adummy_dev;

	if (sysfs_create_group(&atm_dev->class_dev.kobj, &adummy_group_attrs))
		dev_err(&atm_dev->class_dev, "Could not register attrs for adummy\n");

	if (adummy_start(atm_dev)) {
		printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
		err = -ENODEV;
		goto out_unregister;
	}

	list_add(&adummy_dev->entry, &adummy_devs);
out:
	return err;

out_unregister:
	atm_dev_deregister(atm_dev);
out_kfree:
	kfree(adummy_dev);
	goto out;
}

static void __exit adummy_cleanup(void)
{
	struct adummy_dev *adummy_dev, *next;

	list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
		atm_dev_deregister(adummy_dev->atm_dev);
		kfree(adummy_dev);
	}
}

module_init(adummy_init);
module_exit(adummy_cleanup);

MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
MODULE_DESCRIPTION("dummy ATM driver");
MODULE_LICENSE("GPL");
