/* drivers/atm/atmtcp.c - ATM over TCP "device" driver */

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


#include <linux/module.h>
#include <linux/wait.h>
#include <linux/atmdev.h>
#include <linux/atm_tcp.h>
#include <linux/bitops.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>


extern int atm_init_aal5(struct atm_vcc *vcc); /* "raw" AAL5 transport */


#define PRIV(dev) ((struct atmtcp_dev_data *) ((dev)->dev_data))


struct atmtcp_dev_data {
	struct atm_vcc *vcc;	/* control VCC; NULL if detached */
	int persist;		/* non-zero if persistent */
};


#define DEV_LABEL    "atmtcp"

#define MAX_VPI_BITS  8	/* simplifies life */
#define MAX_VCI_BITS 16


/*
 * Hairy code ahead: the control VCC may be closed while we're still
 * waiting for an answer, so we need to re-validate out_vcc every once
 * in a while.
 */


static int atmtcp_send_control(struct atm_vcc *vcc,int type,
    const struct atmtcp_control *msg,int flag)
{
	DECLARE_WAITQUEUE(wait,current);
	struct atm_vcc *out_vcc;
	struct sk_buff *skb;
	struct atmtcp_control *new_msg;
	int old_test;
	int error = 0;

	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
	if (!out_vcc) return -EUNATCH;
	skb = alloc_skb(sizeof(*msg),GFP_KERNEL);
	if (!skb) return -ENOMEM;
	mb();
	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
	if (!out_vcc) {
		dev_kfree_skb(skb);
		return -EUNATCH;
	}
	atm_force_charge(out_vcc,skb->truesize);
	new_msg = (struct atmtcp_control *) skb_put(skb,sizeof(*new_msg));
	*new_msg = *msg;
	new_msg->hdr.length = ATMTCP_HDR_MAGIC;
	new_msg->type = type;
	memset(&new_msg->vcc,0,sizeof(atm_kptr_t));
	*(struct atm_vcc **) &new_msg->vcc = vcc;
	old_test = test_bit(flag,&vcc->flags);
	out_vcc->push(out_vcc,skb);
	add_wait_queue(sk_atm(vcc)->sk_sleep, &wait);
	while (test_bit(flag,&vcc->flags) == old_test) {
		mb();
		out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
		if (!out_vcc) {
			error = -EUNATCH;
			break;
		}
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule();
	}
	set_current_state(TASK_RUNNING);
	remove_wait_queue(sk_atm(vcc)->sk_sleep, &wait);
	return error;
}


static int atmtcp_recv_control(const struct atmtcp_control *msg)
{
	struct atm_vcc *vcc = *(struct atm_vcc **) &msg->vcc;

	vcc->vpi = msg->addr.sap_addr.vpi;
	vcc->vci = msg->addr.sap_addr.vci;
	vcc->qos = msg->qos;
	sk_atm(vcc)->sk_err = -msg->result;
	switch (msg->type) {
	    case ATMTCP_CTRL_OPEN:
		change_bit(ATM_VF_READY,&vcc->flags);
		break;
	    case ATMTCP_CTRL_CLOSE:
		change_bit(ATM_VF_ADDR,&vcc->flags);
		break;
	    default:
		printk(KERN_ERR "atmtcp_recv_control: unknown type %d\n",
		    msg->type);
		return -EINVAL;
	}
	wake_up(sk_atm(vcc)->sk_sleep);
	return 0;
}


static void atmtcp_v_dev_close(struct atm_dev *dev)
{
	/* Nothing.... Isn't this simple :-)  -- REW */
}


static int atmtcp_v_open(struct atm_vcc *vcc)
{
	struct atmtcp_control msg;
	int error;
	short vpi = vcc->vpi;
	int vci = vcc->vci;

	memset(&msg,0,sizeof(msg));
	msg.addr.sap_family = AF_ATMPVC;
	msg.hdr.vpi = htons(vpi);
	msg.addr.sap_addr.vpi = vpi;
	msg.hdr.vci = htons(vci);
	msg.addr.sap_addr.vci = vci;
	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0;
	msg.type = ATMTCP_CTRL_OPEN;
	msg.qos = vcc->qos;
	set_bit(ATM_VF_ADDR,&vcc->flags);
	clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
	error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
	if (error) return error;
	return -sk_atm(vcc)->sk_err;
}


static void atmtcp_v_close(struct atm_vcc *vcc)
{
	struct atmtcp_control msg;

	memset(&msg,0,sizeof(msg));
	msg.addr.sap_family = AF_ATMPVC;
	msg.addr.sap_addr.vpi = vcc->vpi;
	msg.addr.sap_addr.vci = vcc->vci;
	clear_bit(ATM_VF_READY,&vcc->flags);
	(void) atmtcp_send_control(vcc,ATMTCP_CTRL_CLOSE,&msg,ATM_VF_ADDR);
}


static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
	struct atm_cirange ci;
	struct atm_vcc *vcc;
	struct hlist_node *node;
	struct sock *s;
	int i;

	if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
	if (copy_from_user(&ci, arg,sizeof(ci))) return -EFAULT;
	if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
	if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
	if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
	    ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL;
	read_lock(&vcc_sklist_lock);
	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
		struct hlist_head *head = &vcc_hash[i];

		sk_for_each(s, node, head) {
			vcc = atm_sk(s);
			if (vcc->dev != dev)
				continue;
			if ((vcc->vpi >> ci.vpi_bits) ||
			    (vcc->vci >> ci.vci_bits)) {
				read_unlock(&vcc_sklist_lock);
				return -EBUSY;
			}
		}
	}
	read_unlock(&vcc_sklist_lock);
	dev->ci_range = ci;
	return 0;
}


static int atmtcp_v_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
	struct atmtcp_dev_data *dev_data;
	struct atm_vcc *out_vcc=NULL; /* Initializer quietens GCC warning */
	struct sk_buff *new_skb;
	struct atmtcp_hdr *hdr;
	int size;

	if (vcc->qos.txtp.traffic_class == ATM_NONE) {
		if (vcc->pop) vcc->pop(vcc,skb);
		else dev_kfree_skb(skb);
		return -EINVAL;
	}
	dev_data = PRIV(vcc->dev);
	if (dev_data) out_vcc = dev_data->vcc;
	if (!dev_data || !out_vcc) {
		if (vcc->pop) vcc->pop(vcc,skb);
		else dev_kfree_skb(skb);
		if (dev_data) return 0;
		atomic_inc(&vcc->stats->tx_err);
		return -ENOLINK;
	}
	size = skb->len+sizeof(struct atmtcp_hdr);
	new_skb = atm_alloc_charge(out_vcc,size,GFP_ATOMIC);
	if (!new_skb) {
		if (vcc->pop) vcc->pop(vcc,skb);
		else dev_kfree_skb(skb);
		atomic_inc(&vcc->stats->tx_err);
		return -ENOBUFS;
	}
	hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
	hdr->vpi = htons(vcc->vpi);
	hdr->vci = htons(vcc->vci);
	hdr->length = htonl(skb->len);
	memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
	if (vcc->pop) vcc->pop(vcc,skb);
	else dev_kfree_skb(skb);
	out_vcc->push(out_vcc,new_skb);
	atomic_inc(&vcc->stats->tx);
	atomic_inc(&out_vcc->stats->rx);
	return 0;
}


static int atmtcp_v_proc(struct atm_dev *dev,loff_t *pos,char *page)
{
	struct atmtcp_dev_data *dev_data = PRIV(dev);

	if (*pos) return 0;
	if (!dev_data->persist) return sprintf(page,"ephemeral\n");
	return sprintf(page,"persistent, %sconnected\n",
	    dev_data->vcc ? "" : "dis");
}


static void atmtcp_c_close(struct atm_vcc *vcc)
{
	struct atm_dev *atmtcp_dev;
	struct atmtcp_dev_data *dev_data;

	atmtcp_dev = (struct atm_dev *) vcc->dev_data;
	dev_data = PRIV(atmtcp_dev);
	dev_data->vcc = NULL;
	if (dev_data->persist) return;
	atmtcp_dev->dev_data = NULL;
	kfree(dev_data);
	atm_dev_deregister(atmtcp_dev);
	vcc->dev_data = NULL;
	module_put(THIS_MODULE);
}


static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
{
        struct hlist_head *head;
        struct atm_vcc *vcc;
        struct hlist_node *node;
        struct sock *s;

        head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];

        sk_for_each(s, node, head) {
                vcc = atm_sk(s);
                if (vcc->dev == dev &&
                    vcc->vci == vci && vcc->vpi == vpi &&
                    vcc->qos.rxtp.traffic_class != ATM_NONE) {
                                return vcc;
                }
        }
        return NULL;
}


static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
	struct atm_dev *dev;
	struct atmtcp_hdr *hdr;
	struct atm_vcc *out_vcc;
	struct sk_buff *new_skb;
	int result = 0;

	if (!skb->len) return 0;
	dev = vcc->dev_data;
	hdr = (struct atmtcp_hdr *) skb->data;
	if (hdr->length == ATMTCP_HDR_MAGIC) {
		result = atmtcp_recv_control(
		    (struct atmtcp_control *) skb->data);
		goto done;
	}
	read_lock(&vcc_sklist_lock);
	out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
	read_unlock(&vcc_sklist_lock);
	if (!out_vcc) {
		atomic_inc(&vcc->stats->tx_err);
		goto done;
	}
	skb_pull(skb,sizeof(struct atmtcp_hdr));
	new_skb = atm_alloc_charge(out_vcc,skb->len,GFP_KERNEL);
	if (!new_skb) {
		result = -ENOBUFS;
		goto done;
	}
	__net_timestamp(new_skb);
	memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
	out_vcc->push(out_vcc,new_skb);
	atomic_inc(&vcc->stats->tx);
	atomic_inc(&out_vcc->stats->rx);
done:
	if (vcc->pop) vcc->pop(vcc,skb);
	else dev_kfree_skb(skb);
	return result;
}


/*
 * Device operations for the virtual ATM devices created by ATMTCP.
 */


static struct atmdev_ops atmtcp_v_dev_ops = {
	.dev_close	= atmtcp_v_dev_close,
	.open		= atmtcp_v_open,
	.close		= atmtcp_v_close,
	.ioctl		= atmtcp_v_ioctl,
	.send		= atmtcp_v_send,
	.proc_read	= atmtcp_v_proc,
	.owner		= THIS_MODULE
};


/*
 * Device operations for the ATMTCP control device.
 */


static struct atmdev_ops atmtcp_c_dev_ops = {
	.close		= atmtcp_c_close,
	.send		= atmtcp_c_send
};


static struct atm_dev atmtcp_control_dev = {
	.ops		= &atmtcp_c_dev_ops,
	.type		= "atmtcp",
	.number		= 999,
	.lock		= SPIN_LOCK_UNLOCKED
};


static int atmtcp_create(int itf,int persist,struct atm_dev **result)
{
	struct atmtcp_dev_data *dev_data;
	struct atm_dev *dev;

	dev_data = kmalloc(sizeof(*dev_data),GFP_KERNEL);
	if (!dev_data)
		return -ENOMEM;

	dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
	if (!dev) {
		kfree(dev_data);
		return itf == -1 ? -ENOMEM : -EBUSY;
	}
	dev->ci_range.vpi_bits = MAX_VPI_BITS;
	dev->ci_range.vci_bits = MAX_VCI_BITS;
	dev->dev_data = dev_data;
	PRIV(dev)->vcc = NULL;
	PRIV(dev)->persist = persist;
	if (result) *result = dev;
	return 0;
}


static int atmtcp_attach(struct atm_vcc *vcc,int itf)
{
	struct atm_dev *dev;

	dev = NULL;
	if (itf != -1) dev = atm_dev_lookup(itf);
	if (dev) {
		if (dev->ops != &atmtcp_v_dev_ops) {
			atm_dev_put(dev);
			return -EMEDIUMTYPE;
		}
		if (PRIV(dev)->vcc) return -EBUSY;
	}
	else {
		int error;

		error = atmtcp_create(itf,0,&dev);
		if (error) return error;
	}
	PRIV(dev)->vcc = vcc;
	vcc->dev = &atmtcp_control_dev;
	vcc_insert_socket(sk_atm(vcc));
	set_bit(ATM_VF_META,&vcc->flags);
	set_bit(ATM_VF_READY,&vcc->flags);
	vcc->dev_data = dev;
	(void) atm_init_aal5(vcc); /* @@@ losing AAL in transit ... */
	vcc->stats = &atmtcp_control_dev.stats.aal5;
	return dev->number;
}


static int atmtcp_create_persistent(int itf)
{
	return atmtcp_create(itf,1,NULL);
}


static int atmtcp_remove_persistent(int itf)
{
	struct atm_dev *dev;
	struct atmtcp_dev_data *dev_data;

	dev = atm_dev_lookup(itf);
	if (!dev) return -ENODEV;
	if (dev->ops != &atmtcp_v_dev_ops) {
		atm_dev_put(dev);
		return -EMEDIUMTYPE;
	}
	dev_data = PRIV(dev);
	if (!dev_data->persist) return 0;
	dev_data->persist = 0;
	if (PRIV(dev)->vcc) return 0;
	kfree(dev_data);
	atm_dev_put(dev);
	atm_dev_deregister(dev);
	return 0;
}

static int atmtcp_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
	int err = 0;
	struct atm_vcc *vcc = ATM_SD(sock);

	if (cmd != SIOCSIFATMTCP && cmd != ATMTCP_CREATE && cmd != ATMTCP_REMOVE)
		return -ENOIOCTLCMD;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	switch (cmd) {
		case SIOCSIFATMTCP:
			err = atmtcp_attach(vcc, (int) arg);
			if (err >= 0) {
				sock->state = SS_CONNECTED;
				__module_get(THIS_MODULE);
			}
			break;
		case ATMTCP_CREATE:
			err = atmtcp_create_persistent((int) arg);
			break;
		case ATMTCP_REMOVE:
			err = atmtcp_remove_persistent((int) arg);
			break;
	}
	return err;
}

static struct atm_ioctl atmtcp_ioctl_ops = {
	.owner 	= THIS_MODULE,
	.ioctl	= atmtcp_ioctl,
};

static __init int atmtcp_init(void)
{
	register_atm_ioctl(&atmtcp_ioctl_ops);
	return 0;
}


static void __exit atmtcp_exit(void)
{
	deregister_atm_ioctl(&atmtcp_ioctl_ops);
}

MODULE_LICENSE("GPL");
module_init(atmtcp_init);
module_exit(atmtcp_exit);
