File: /usr/src/linux/drivers/atm/atmtcp.c

1     /* drivers/atm/atmtcp.c - ATM over TCP "device" driver */
2     
3     /* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
4     
5     
6     #include <linux/module.h>
7     #include <linux/wait.h>
8     #include <linux/atmdev.h>
9     #include <linux/atm_tcp.h>
10     #include <linux/bitops.h>
11     #include <asm/uaccess.h>
12     #include <asm/atomic.h>
13     
14     
15     extern int atm_init_aal5(struct atm_vcc *vcc); /* "raw" AAL5 transport */
16     
17     
18     #define PRIV(dev) ((struct atmtcp_dev_data *) ((dev)->dev_data))
19     
20     
21     struct atmtcp_dev_data {
22     	struct atm_vcc *vcc;	/* control VCC; NULL if detached */
23     	int persist;		/* non-zero if persistent */
24     };
25     
26     
27     #define DEV_LABEL    "atmtcp"
28     
29     #define MAX_VPI_BITS  8	/* simplifies life */
30     #define MAX_VCI_BITS 16
31     
32     
33     /*
34      * Hairy code ahead: the control VCC may be closed while we're still
35      * waiting for an answer, so we need to re-validate out_vcc every once
36      * in a while.
37      */
38     
39     
40     static int atmtcp_send_control(struct atm_vcc *vcc,int type,
41         const struct atmtcp_control *msg,int flag)
42     {
43     	DECLARE_WAITQUEUE(wait,current);
44     	struct atm_vcc *out_vcc;
45     	struct sk_buff *skb;
46     	struct atmtcp_control *new_msg;
47     	int old_test;
48     	int error = 0;
49     
50     	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
51     	if (!out_vcc) return -EUNATCH;
52     	skb = alloc_skb(sizeof(*msg),GFP_KERNEL);
53     	if (!skb) return -ENOMEM;
54     	mb();
55     	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
56     	if (!out_vcc) {
57     		dev_kfree_skb(skb);
58     		return -EUNATCH;
59     	}
60     	atm_force_charge(out_vcc,skb->truesize);
61     	new_msg = (struct atmtcp_control *) skb_put(skb,sizeof(*new_msg));
62     	*new_msg = *msg;
63     	new_msg->hdr.length = ATMTCP_HDR_MAGIC;
64     	new_msg->type = type;
65     	memset(&new_msg->vcc,0,sizeof(atm_kptr_t));
66     	*(struct atm_vcc **) &new_msg->vcc = vcc;
67     	old_test = test_bit(flag,&vcc->flags);
68     	out_vcc->push(out_vcc,skb);
69     	add_wait_queue(&vcc->sleep,&wait);
70     	while (test_bit(flag,&vcc->flags) == old_test) {
71     		mb();
72     		out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
73     		if (!out_vcc) {
74     			error = -EUNATCH;
75     			break;
76     		}
77     		set_current_state(TASK_UNINTERRUPTIBLE);
78     		schedule();
79     	}
80     	current->state = TASK_RUNNING;
81     	remove_wait_queue(&vcc->sleep,&wait);
82     	return error;
83     }
84     
85     
86     static int atmtcp_recv_control(const struct atmtcp_control *msg)
87     {
88     	struct atm_vcc *vcc = *(struct atm_vcc **) &msg->vcc;
89     
90     	vcc->vpi = msg->addr.sap_addr.vpi;
91     	vcc->vci = msg->addr.sap_addr.vci;
92     	vcc->qos = msg->qos;
93     	vcc->reply = msg->result;
94     	switch (msg->type) {
95     	    case ATMTCP_CTRL_OPEN:
96     		change_bit(ATM_VF_READY,&vcc->flags);
97     		break;
98     	    case ATMTCP_CTRL_CLOSE:
99     		change_bit(ATM_VF_ADDR,&vcc->flags);
100     		break;
101     	    default:
102     		printk(KERN_ERR "atmtcp_recv_control: unknown type %d\n",
103     		    msg->type);
104     		return -EINVAL;
105     	}
106     	wake_up(&vcc->sleep);
107     	return 0;
108     }
109     
110     
111     static void atmtcp_v_dev_close(struct atm_dev *dev)
112     {
113     	/* Nothing.... Isn't this simple :-)  -- REW */
114     }
115     
116     
117     static int atmtcp_v_open(struct atm_vcc *vcc,short vpi,int vci)
118     {
119     	struct atmtcp_control msg;
120     	int error;
121     
122     	memset(&msg,0,sizeof(msg));
123     	msg.addr.sap_family = AF_ATMPVC;
124     	msg.hdr.vpi = htons(vpi);
125     	msg.addr.sap_addr.vpi = vpi;
126     	msg.hdr.vci = htons(vci);
127     	msg.addr.sap_addr.vci = vci;
128     	error = atm_find_ci(vcc,&msg.addr.sap_addr.vpi,&msg.addr.sap_addr.vci);
129     	if (error) return error;
130     	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0;
131     	msg.type = ATMTCP_CTRL_OPEN;
132     	msg.qos = vcc->qos;
133     	set_bit(ATM_VF_ADDR,&vcc->flags);
134     	clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
135     	error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
136     	if (error) return error;
137     	return vcc->reply;
138     }
139     
140     
141     static void atmtcp_v_close(struct atm_vcc *vcc)
142     {
143     	struct atmtcp_control msg;
144     
145     	memset(&msg,0,sizeof(msg));
146     	msg.addr.sap_family = AF_ATMPVC;
147     	msg.addr.sap_addr.vpi = vcc->vpi;
148     	msg.addr.sap_addr.vci = vcc->vci;
149     	clear_bit(ATM_VF_READY,&vcc->flags);
150     	(void) atmtcp_send_control(vcc,ATMTCP_CTRL_CLOSE,&msg,ATM_VF_ADDR);
151     }
152     
153     
154     static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
155     {
156     	struct atm_cirange ci;
157     	struct atm_vcc *vcc;
158     
159     	if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
160     	if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT;
161     	if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
162     	if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
163     	if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
164     	    ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL;
165     	for (vcc = dev->vccs; vcc; vcc = vcc->next)
166     		if ((vcc->vpi >> ci.vpi_bits) ||
167     		    (vcc->vci >> ci.vci_bits)) return -EBUSY;
168     	dev->ci_range = ci;
169     	return 0;
170     }
171     
172     
173     static int atmtcp_v_send(struct atm_vcc *vcc,struct sk_buff *skb)
174     {
175     	struct atmtcp_dev_data *dev_data;
176     	struct atm_vcc *out_vcc;
177     	struct sk_buff *new_skb;
178     	struct atmtcp_hdr *hdr;
179     	int size;
180     
181     	if (vcc->qos.txtp.traffic_class == ATM_NONE) {
182     		if (vcc->pop) vcc->pop(vcc,skb);
183     		else dev_kfree_skb(skb);
184     		return -EINVAL;
185     	}
186     	dev_data = PRIV(vcc->dev);
187     	if (dev_data) out_vcc = dev_data->vcc;
188     	if (!dev_data || !out_vcc) {
189     		if (vcc->pop) vcc->pop(vcc,skb);
190     		else dev_kfree_skb(skb);
191     		if (dev_data) return 0;
192     		atomic_inc(&vcc->stats->tx_err);
193     		return -ENOLINK;
194     	}
195     	size = skb->len+sizeof(struct atmtcp_hdr);
196     	new_skb = atm_alloc_charge(out_vcc,size,GFP_ATOMIC);
197     	if (!new_skb) {
198     		if (vcc->pop) vcc->pop(vcc,skb);
199     		else dev_kfree_skb(skb);
200     		atomic_inc(&vcc->stats->tx_err);
201     		return -ENOBUFS;
202     	}
203     	hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
204     	hdr->vpi = htons(vcc->vpi);
205     	hdr->vci = htons(vcc->vci);
206     	hdr->length = htonl(skb->len);
207     	memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
208     	if (vcc->pop) vcc->pop(vcc,skb);
209     	else dev_kfree_skb(skb);
210     	out_vcc->push(out_vcc,new_skb);
211     	atomic_inc(&vcc->stats->tx);
212     	atomic_inc(&out_vcc->stats->rx);
213     	return 0;
214     }
215     
216     
217     static int atmtcp_v_proc(struct atm_dev *dev,loff_t *pos,char *page)
218     {
219     	struct atmtcp_dev_data *dev_data = PRIV(dev);
220     
221     	if (*pos) return 0;
222     	if (!dev_data->persist) return sprintf(page,"ephemeral\n");
223     	return sprintf(page,"persistent, %sconnected\n",
224     	    dev_data->vcc ? "" : "dis");
225     }
226     
227     
228     static void atmtcp_c_close(struct atm_vcc *vcc)
229     {
230     	struct atm_dev *atmtcp_dev;
231     	struct atmtcp_dev_data *dev_data;
232     	struct atm_vcc *walk;
233     
234     	atmtcp_dev = (struct atm_dev *) vcc->dev_data;
235     	dev_data = PRIV(atmtcp_dev);
236     	dev_data->vcc = NULL;
237     	if (dev_data->persist) return;
238     	PRIV(atmtcp_dev) = NULL;
239     	kfree(dev_data);
240     	shutdown_atm_dev(atmtcp_dev);
241     	vcc->dev_data = NULL;
242     	for (walk = atmtcp_dev->vccs; walk; walk = walk->next)
243     		wake_up(&walk->sleep);
244     }
245     
246     
247     static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
248     {
249     	struct atm_dev *dev;
250     	struct atmtcp_hdr *hdr;
251     	struct atm_vcc *out_vcc;
252     	struct sk_buff *new_skb;
253     	int result = 0;
254     
255     	if (!skb->len) return 0;
256     	dev = vcc->dev_data;
257     	hdr = (struct atmtcp_hdr *) skb->data;
258     	if (hdr->length == ATMTCP_HDR_MAGIC) {
259     		result = atmtcp_recv_control(
260     		    (struct atmtcp_control *) skb->data);
261     		goto done;
262     	}
263     	for (out_vcc = dev->vccs; out_vcc; out_vcc = out_vcc->next)
264     		if (out_vcc->vpi == ntohs(hdr->vpi) &&
265     		    out_vcc->vci == ntohs(hdr->vci) &&
266     		    out_vcc->qos.rxtp.traffic_class != ATM_NONE)
267     			break;
268     	if (!out_vcc) {
269     		atomic_inc(&vcc->stats->tx_err);
270     		goto done;
271     	}
272     	skb_pull(skb,sizeof(struct atmtcp_hdr));
273     	new_skb = atm_alloc_charge(out_vcc,skb->len,GFP_KERNEL);
274     	if (!new_skb) {
275     		result = -ENOBUFS;
276     		goto done;
277     	}
278     	new_skb->stamp = xtime;
279     	memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
280     	out_vcc->push(out_vcc,new_skb);
281     	atomic_inc(&vcc->stats->tx);
282     	atomic_inc(&out_vcc->stats->rx);
283     done:
284     	if (vcc->pop) vcc->pop(vcc,skb);
285     	else dev_kfree_skb(skb);
286     	return result;
287     }
288     
289     
290     /*
291      * Device operations for the virtual ATM devices created by ATMTCP.
292      */
293     
294     
295     static struct atmdev_ops atmtcp_v_dev_ops = {
296     	dev_close:	atmtcp_v_dev_close,
297     	open:		atmtcp_v_open,
298     	close:		atmtcp_v_close,
299     	ioctl:		atmtcp_v_ioctl,
300     	send:		atmtcp_v_send,
301     	proc_read:	atmtcp_v_proc,
302     	owner:		THIS_MODULE
303     };
304     
305     
306     /*
307      * Device operations for the ATMTCP control device.
308      */
309     
310     
311     static struct atmdev_ops atmtcp_c_dev_ops = {
312     	close:		atmtcp_c_close,
313     	send:		atmtcp_c_send
314     };
315     
316     
317     static struct atm_dev atmtcp_control_dev = {
318     	&atmtcp_c_dev_ops,
319     	NULL,		/* no PHY */
320     	"atmtcp",	/* type */
321     	999,		/* dummy device number */
322     	NULL,NULL,	/* pretend not to have any VCCs */
323     	NULL,NULL,	/* no data */
324     	{ 0 },		/* no flags */
325     	NULL,		/* no local address */
326     	{ 0 }		/* no ESI, no statistics */
327     };
328     
329     
330     static int atmtcp_create(int itf,int persist,struct atm_dev **result)
331     {
332     	struct atmtcp_dev_data *dev_data;
333     	struct atm_dev *dev;
334     
335     	dev_data = kmalloc(sizeof(*dev_data),GFP_KERNEL);
336     	if (!dev_data)
337     		return -ENOMEM;
338     
339     	dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
340     	if (!dev) {
341     		kfree(dev_data);
342     		return itf == -1 ? -ENOMEM : -EBUSY;
343     	}
344     	dev->ci_range.vpi_bits = MAX_VPI_BITS;
345     	dev->ci_range.vci_bits = MAX_VCI_BITS;
346     	PRIV(dev) = dev_data;
347     	PRIV(dev)->vcc = NULL;
348     	PRIV(dev)->persist = persist;
349     	if (result) *result = dev;
350     	return 0;
351     }
352     
353     
354     int atmtcp_attach(struct atm_vcc *vcc,int itf)
355     {
356     	struct atm_dev *dev;
357     
358     	dev = NULL;
359     	if (itf != -1) dev = atm_find_dev(itf);
360     	if (dev) {
361     		if (dev->ops != &atmtcp_v_dev_ops) return -EMEDIUMTYPE;
362     		if (PRIV(dev)->vcc) return -EBUSY;
363     	}
364     	else {
365     		int error;
366     
367     		error = atmtcp_create(itf,0,&dev);
368     		if (error) return error;
369     	}
370     	PRIV(dev)->vcc = vcc;
371     	bind_vcc(vcc,&atmtcp_control_dev);
372     	set_bit(ATM_VF_META,&vcc->flags);
373     	set_bit(ATM_VF_READY,&vcc->flags);
374     	vcc->dev_data = dev;
375     	(void) atm_init_aal5(vcc); /* @@@ losing AAL in transit ... */
376     	vcc->stats = &atmtcp_control_dev.stats.aal5;
377     	return dev->number;
378     }
379     
380     
381     int atmtcp_create_persistent(int itf)
382     {
383     	return atmtcp_create(itf,1,NULL);
384     }
385     
386     
387     int atmtcp_remove_persistent(int itf)
388     {
389     	struct atm_dev *dev;
390     	struct atmtcp_dev_data *dev_data;
391     
392     	dev = atm_find_dev(itf);
393     	if (!dev) return -ENODEV;
394     	if (dev->ops != &atmtcp_v_dev_ops) return -EMEDIUMTYPE;
395     	dev_data = PRIV(dev);
396     	if (!dev_data->persist) return 0;
397     	dev_data->persist = 0;
398     	if (PRIV(dev)->vcc) return 0;
399     	kfree(dev_data);
400     	shutdown_atm_dev(dev);
401     	return 0;
402     }
403     
404     
405     #ifdef MODULE
406     
407     int init_module(void)
408     {
409     	atm_tcp_ops.attach = atmtcp_attach;
410     	atm_tcp_ops.create_persistent = atmtcp_create_persistent;
411     	atm_tcp_ops.remove_persistent = atmtcp_remove_persistent;
412     	return 0;
413     }
414     
415     
416     void cleanup_module(void)
417     {
418     	atm_tcp_ops.attach = NULL;
419     	atm_tcp_ops.create_persistent = NULL;
420     	atm_tcp_ops.remove_persistent = NULL;
421     }
422     
423     MODULE_LICENSE("GPL");
424     #else
425     
426     struct atm_tcp_ops atm_tcp_ops = {
427     	atmtcp_attach,			/* attach */
428     	atmtcp_create_persistent,	/* create_persistent */
429     	atmtcp_remove_persistent	/* remove_persistent */
430     };
431     
432     #endif
433