blob: d3b28b01b9f91c5e5e52cfb5eb9a60940cb07531 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2* cycx_x25.c Cyclom 2X WAN Link Driver. X.25 module.
3*
4* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5*
6* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
7*
8* Based on sdla_x25.c by Gene Kozin <genek@compuserve.com>
9*
10* This program is free software; you can redistribute it and/or
11* modify it under the terms of the GNU General Public License
12* as published by the Free Software Foundation; either version
13* 2 of the License, or (at your option) any later version.
14* ============================================================================
15* 2001/01/12 acme use dev_kfree_skb_irq on interrupt context
16* 2000/04/02 acme dprintk, cycx_debug
17* fixed the bug introduced in get_dev_by_lcn and
18* get_dev_by_dte_addr by the anonymous hacker
19* that converted this driver to softnet
20* 2000/01/08 acme cleanup
21* 1999/10/27 acme use ARPHRD_HWX25 so that the X.25 stack know
22* that we have a X.25 stack implemented in
23* firmware onboard
24* 1999/10/18 acme support for X.25 sockets in if_send,
25* beware: socket(AF_X25...) IS WORK IN PROGRESS,
26* TCP/IP over X.25 via wanrouter not affected,
27* working.
28* 1999/10/09 acme chan_disc renamed to chan_disconnect,
29* began adding support for X.25 sockets:
30* conf->protocol in new_if
31* 1999/10/05 acme fixed return E... to return -E...
32* 1999/08/10 acme serialized access to the card thru a spinlock
33* in x25_exec
34* 1999/08/09 acme removed per channel spinlocks
35* removed references to enable_tx_int
36* 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated
37* if_send simplified
38* 1999/05/25 acme fixed t1, t2, t21 & t23 configuration
39* use spinlocks instead of cli/sti in some points
40* 1999/05/24 acme finished the x25_get_stat function
41* 1999/05/23 acme dev->type = ARPHRD_X25 (tcpdump only works,
42* AFAIT, with ARPHRD_ETHER). This seems to be
43* needed to use socket(AF_X25)...
44* Now the config file must specify a peer media
45* address for svc channels over a crossover cable.
46* Removed hold_timeout from x25_channel_t,
47* not used.
48* A little enhancement in the DEBUG processing
49* 1999/05/22 acme go to DISCONNECTED in disconnect_confirm_intr,
50* instead of chan_disc.
51* 1999/05/16 marcelo fixed timer initialization in SVCs
52* 1999/01/05 acme x25_configure now get (most of) all
53* parameters...
54* 1999/01/05 acme pktlen now (correctly) uses log2 (value
55* configured)
56* 1999/01/03 acme judicious use of data types (u8, u16, u32, etc)
57* 1999/01/03 acme cyx_isr: reset dpmbase to acknowledge
58* indication (interrupt from cyclom 2x)
59* 1999/01/02 acme cyx_isr: first hackings...
60* 1999/01/0203 acme when initializing an array don't give less
61* elements than declared...
62* example: char send_cmd[6] = "?\xFF\x10";
63* you'll gonna lose a couple hours, 'cause your
64* brain won't admit that there's an error in the
65* above declaration... the side effect is that
66* memset is put into the unresolved symbols
67* instead of using the inline memset functions...
68* 1999/01/02 acme began chan_connect, chan_send, x25_send
69* 1998/12/31 acme x25_configure
70* this code can be compiled as non module
71* 1998/12/27 acme code cleanup
72* IPX code wiped out! let's decrease code
73* complexity for now, remember: I'm learning! :)
74* bps_to_speed_code OK
75* 1998/12/26 acme Minimal debug code cleanup
76* 1998/08/08 acme Initial version.
77*/
78
79#define CYCLOMX_X25_DEBUG 1
80
Tobias Klauser8e18d1f2005-09-10 14:45:00 -070081#include <linux/ctype.h> /* isdigit() */
Linus Torvalds1da177e2005-04-16 15:20:36 -070082#include <linux/errno.h> /* return codes */
83#include <linux/if_arp.h> /* ARPHRD_HWX25 */
84#include <linux/kernel.h> /* printk(), and other useful stuff */
85#include <linux/module.h>
86#include <linux/string.h> /* inline memset(), etc. */
87#include <linux/slab.h> /* kmalloc(), kfree() */
88#include <linux/stddef.h> /* offsetof(), etc. */
89#include <linux/wanrouter.h> /* WAN router definitions */
90
91#include <asm/byteorder.h> /* htons(), etc. */
92
93#include <linux/cyclomx.h> /* Cyclom 2X common user API definitions */
94#include <linux/cycx_x25.h> /* X.25 firmware API definitions */
95
96#include <net/x25device.h>
97
98/* Defines & Macros */
99#define CYCX_X25_MAX_CMD_RETRY 5
100#define CYCX_X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
101
102/* Data Structures */
103/* This is an extension of the 'struct net_device' we create for each network
104 interface to keep the rest of X.25 channel-specific data. */
105struct cycx_x25_channel {
106 /* This member must be first. */
107 struct net_device *slave; /* WAN slave */
108
109 char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
110 char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
111 char *local_addr; /* local media address, ASCIIZ -
112 svc thru crossover cable */
113 s16 lcn; /* logical channel number/conn.req.key*/
114 u8 link;
115 struct timer_list timer; /* timer used for svc channel disc. */
116 u16 protocol; /* ethertype, 0 - multiplexed */
117 u8 svc; /* 0 - permanent, 1 - switched */
118 u8 state; /* channel state */
119 u8 drop_sequence; /* mark sequence for dropping */
120 u32 idle_tmout; /* sec, before disconnecting */
121 struct sk_buff *rx_skb; /* receive socket buffer */
122 struct cycx_device *card; /* -> owner */
123 struct net_device_stats ifstats;/* interface statistics */
124};
125
126/* Function Prototypes */
127/* WAN link driver entry points. These are called by the WAN router module. */
128static int cycx_wan_update(struct wan_device *wandev),
129 cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
130 wanif_conf_t *conf),
131 cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
132
133/* Network device interface */
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700134static int cycx_netdevice_init(struct net_device *dev);
135static int cycx_netdevice_open(struct net_device *dev);
136static int cycx_netdevice_stop(struct net_device *dev);
137static int cycx_netdevice_hard_header(struct sk_buff *skb,
138 struct net_device *dev, u16 type,
139 const void *daddr, const void *saddr,
140 unsigned len);
141static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
142static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143 struct net_device *dev);
144
145static struct net_device_stats *
146 cycx_netdevice_get_stats(struct net_device *dev);
147
148/* Interrupt handlers */
149static void cycx_x25_irq_handler(struct cycx_device *card),
150 cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
151 cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
152 cycx_x25_irq_log(struct cycx_device *card,
153 struct cycx_x25_cmd *cmd),
154 cycx_x25_irq_stat(struct cycx_device *card,
155 struct cycx_x25_cmd *cmd),
156 cycx_x25_irq_connect_confirm(struct cycx_device *card,
157 struct cycx_x25_cmd *cmd),
158 cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
159 struct cycx_x25_cmd *cmd),
160 cycx_x25_irq_connect(struct cycx_device *card,
161 struct cycx_x25_cmd *cmd),
162 cycx_x25_irq_disconnect(struct cycx_device *card,
163 struct cycx_x25_cmd *cmd),
164 cycx_x25_irq_spurious(struct cycx_device *card,
165 struct cycx_x25_cmd *cmd);
166
167/* X.25 firmware interface functions */
168static int cycx_x25_configure(struct cycx_device *card,
169 struct cycx_x25_config *conf),
170 cycx_x25_get_stats(struct cycx_device *card),
171 cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
172 int len, void *buf),
173 cycx_x25_connect_response(struct cycx_device *card,
174 struct cycx_x25_channel *chan),
175 cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
176 u8 lcn);
177
178/* channel functions */
179static int cycx_x25_chan_connect(struct net_device *dev),
180 cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb);
181
182static void cycx_x25_chan_disconnect(struct net_device *dev),
183 cycx_x25_chan_send_event(struct net_device *dev, u8 event);
184
185/* Miscellaneous functions */
186static void cycx_x25_set_chan_state(struct net_device *dev, u8 state),
187 cycx_x25_chan_timer(unsigned long d);
188
189static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble),
190 reset_timer(struct net_device *dev);
191
192static u8 bps_to_speed_code(u32 bps);
193static u8 cycx_log2(u32 n);
194
195static unsigned dec_to_uint(u8 *str, int len);
196
197static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
198 s16 lcn);
199static struct net_device *
200 cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
201
202#ifdef CYCLOMX_X25_DEBUG
203static void hex_dump(char *msg, unsigned char *p, int len);
204static void cycx_x25_dump_config(struct cycx_x25_config *conf);
205static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
206static void cycx_x25_dump_devs(struct wan_device *wandev);
207#else
208#define hex_dump(msg, p, len)
209#define cycx_x25_dump_config(conf)
210#define cycx_x25_dump_stats(stats)
211#define cycx_x25_dump_devs(wandev)
212#endif
213/* Public Functions */
214
215/* X.25 Protocol Initialization routine.
216 *
217 * This routine is called by the main Cyclom 2X module during setup. At this
218 * point adapter is completely initialized and X.25 firmware is running.
219 * o configure adapter
220 * o initialize protocol-specific fields of the adapter data space.
221 *
222 * Return: 0 o.k.
223 * < 0 failure. */
224int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
225{
226 struct cycx_x25_config cfg;
227
228 /* Verify configuration ID */
229 if (conf->config_id != WANCONFIG_X25) {
230 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
231 card->devname, conf->config_id);
232 return -EINVAL;
233 }
234
235 /* Initialize protocol-specific fields */
236 card->mbox = card->hw.dpmbase + X25_MBOX_OFFS;
237 card->u.x.connection_keys = 0;
238 spin_lock_init(&card->u.x.lock);
239
240 /* Configure adapter. Here we set reasonable defaults, then parse
241 * device configuration structure and set configuration options.
242 * Most configuration options are verified and corrected (if
243 * necessary) since we can't rely on the adapter to do so and don't
244 * want it to fail either. */
245 memset(&cfg, 0, sizeof(cfg));
246 cfg.link = 0;
247 cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
248 cfg.speed = bps_to_speed_code(conf->bps);
249 cfg.n3win = 7;
250 cfg.n2win = 2;
251 cfg.n2 = 5;
252 cfg.nvc = 1;
253 cfg.npvc = 1;
254 cfg.flags = 0x02; /* default = V35 */
255 cfg.t1 = 10; /* line carrier timeout */
256 cfg.t2 = 29; /* tx timeout */
257 cfg.t21 = 180; /* CALL timeout */
258 cfg.t23 = 180; /* CLEAR timeout */
259
260 /* adjust MTU */
261 if (!conf->mtu || conf->mtu >= 512)
262 card->wandev.mtu = 512;
263 else if (conf->mtu >= 256)
264 card->wandev.mtu = 256;
265 else if (conf->mtu >= 128)
266 card->wandev.mtu = 128;
267 else
268 card->wandev.mtu = 64;
269
270 cfg.pktlen = cycx_log2(card->wandev.mtu);
271
272 if (conf->station == WANOPT_DTE) {
273 cfg.locaddr = 3; /* DTE */
274 cfg.remaddr = 1; /* DCE */
275 } else {
276 cfg.locaddr = 1; /* DCE */
277 cfg.remaddr = 3; /* DTE */
278 }
279
280 if (conf->interface == WANOPT_RS232)
281 cfg.flags = 0; /* FIXME just reset the 2nd bit */
282
283 if (conf->u.x25.hi_pvc) {
284 card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
285 card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
286 }
287
288 if (conf->u.x25.hi_svc) {
289 card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
290 card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
291 }
292
293 if (card->u.x.lo_pvc == 255)
294 cfg.npvc = 0;
295 else
296 cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
297
298 cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
299
300 if (conf->u.x25.hdlc_window)
301 cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
302
303 if (conf->u.x25.pkt_window)
304 cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
305
306 if (conf->u.x25.t1)
307 cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
308
309 if (conf->u.x25.t2)
310 cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
311
312 if (conf->u.x25.t11_t21)
313 cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
314
315 if (conf->u.x25.t13_t23)
316 cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
317
318 if (conf->u.x25.n2)
319 cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
320
321 /* initialize adapter */
322 if (cycx_x25_configure(card, &cfg))
323 return -EIO;
324
325 /* Initialize protocol-specific fields of adapter data space */
326 card->wandev.bps = conf->bps;
327 card->wandev.interface = conf->interface;
328 card->wandev.clocking = conf->clocking;
329 card->wandev.station = conf->station;
330 card->isr = cycx_x25_irq_handler;
331 card->exec = NULL;
332 card->wandev.update = cycx_wan_update;
333 card->wandev.new_if = cycx_wan_new_if;
334 card->wandev.del_if = cycx_wan_del_if;
335 card->wandev.state = WAN_DISCONNECTED;
336
337 return 0;
338}
339
340/* WAN Device Driver Entry Points */
341/* Update device status & statistics. */
342static int cycx_wan_update(struct wan_device *wandev)
343{
344 /* sanity checks */
345 if (!wandev || !wandev->private)
346 return -EFAULT;
347
348 if (wandev->state == WAN_UNCONFIGURED)
349 return -ENODEV;
350
351 cycx_x25_get_stats(wandev->private);
352
353 return 0;
354}
355
356/* Create new logical channel.
357 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
358 * handled.
359 * o parse media- and hardware-specific configuration
360 * o make sure that a new channel can be created
361 * o allocate resources, if necessary
362 * o prepare network device structure for registration.
363 *
364 * Return: 0 o.k.
365 * < 0 failure (channel will not be created) */
366static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
367 wanif_conf_t *conf)
368{
369 struct cycx_device *card = wandev->private;
370 struct cycx_x25_channel *chan;
371 int err = 0;
372
373 if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
374 printk(KERN_INFO "%s: invalid interface name!\n",
375 card->devname);
376 return -EINVAL;
377 }
378
379 /* allocate and initialize private data */
Yoann Padioleaudd00cc42007-07-19 01:49:03 -0700380 chan = kzalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 if (!chan)
382 return -ENOMEM;
383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 strcpy(chan->name, conf->name);
385 chan->card = card;
386 chan->link = conf->port;
387 chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
388 chan->rx_skb = NULL;
389 /* only used in svc connected thru crossover cable */
390 chan->local_addr = NULL;
391
392 if (conf->addr[0] == '@') { /* SVC */
393 int len = strlen(conf->local_addr);
394
395 if (len) {
396 if (len > WAN_ADDRESS_SZ) {
397 printk(KERN_ERR "%s: %s local addr too long!\n",
398 wandev->name, chan->name);
399 kfree(chan);
400 return -EINVAL;
401 } else {
402 chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
403
404 if (!chan->local_addr) {
405 kfree(chan);
406 return -ENOMEM;
407 }
408 }
409
410 strncpy(chan->local_addr, conf->local_addr,
411 WAN_ADDRESS_SZ);
412 }
413
414 chan->svc = 1;
415 strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
416 init_timer(&chan->timer);
417 chan->timer.function = cycx_x25_chan_timer;
418 chan->timer.data = (unsigned long)dev;
419
420 /* Set channel timeouts (default if not specified) */
421 chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
Tobias Klauser8e18d1f2005-09-10 14:45:00 -0700422 } else if (isdigit(conf->addr[0])) { /* PVC */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 s16 lcn = dec_to_uint(conf->addr, 0);
424
425 if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
426 chan->lcn = lcn;
427 else {
428 printk(KERN_ERR
429 "%s: PVC %u is out of range on interface %s!\n",
430 wandev->name, lcn, chan->name);
431 err = -EINVAL;
432 }
433 } else {
434 printk(KERN_ERR "%s: invalid media address on interface %s!\n",
435 wandev->name, chan->name);
436 err = -EINVAL;
437 }
438
439 if (err) {
Jesper Juhl6a5d3622005-05-03 14:33:27 -0700440 kfree(chan->local_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 kfree(chan);
442 return err;
443 }
444
445 /* prepare network device data space for registration */
446 strcpy(dev->name, chan->name);
447 dev->init = cycx_netdevice_init;
448 dev->priv = chan;
449
450 return 0;
451}
452
453/* Delete logical channel. */
454static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
455{
456 if (dev->priv) {
457 struct cycx_x25_channel *chan = dev->priv;
458
459 if (chan->svc) {
Jesper Juhl6a5d3622005-05-03 14:33:27 -0700460 kfree(chan->local_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 if (chan->state == WAN_CONNECTED)
462 del_timer(&chan->timer);
463 }
464
465 kfree(chan);
466 dev->priv = NULL;
467 }
468
469 return 0;
470}
471
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700472
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473/* Network Device Interface */
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700474
475static const struct header_ops cycx_header_ops = {
476 .create = cycx_netdevice_hard_header,
477 .rebuild = cycx_netdevice_rebuild_header,
478};
479
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480/* Initialize Linux network interface.
481 *
482 * This routine is called only once for each interface, during Linux network
483 * interface registration. Returning anything but zero will fail interface
484 * registration. */
485static int cycx_netdevice_init(struct net_device *dev)
486{
487 struct cycx_x25_channel *chan = dev->priv;
488 struct cycx_device *card = chan->card;
489 struct wan_device *wandev = &card->wandev;
490
491 /* Initialize device driver entry points */
492 dev->open = cycx_netdevice_open;
493 dev->stop = cycx_netdevice_stop;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700494 dev->header_ops = &cycx_header_ops;
495
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 dev->hard_start_xmit = cycx_netdevice_hard_start_xmit;
497 dev->get_stats = cycx_netdevice_get_stats;
498
499 /* Initialize media-specific parameters */
500 dev->mtu = CYCX_X25_CHAN_MTU;
501 dev->type = ARPHRD_HWX25; /* ARP h/w type */
502 dev->hard_header_len = 0; /* media header length */
503 dev->addr_len = 0; /* hardware address length */
504
505 if (!chan->svc)
Al Viro7fd71e52007-12-22 17:27:24 +0000506 *(__be16*)dev->dev_addr = htons(chan->lcn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
508 /* Initialize hardware parameters (just for reference) */
509 dev->irq = wandev->irq;
510 dev->dma = wandev->dma;
511 dev->base_addr = wandev->ioport;
512 dev->mem_start = (unsigned long)wandev->maddr;
513 dev->mem_end = (unsigned long)(wandev->maddr +
514 wandev->msize - 1);
515 dev->flags |= IFF_NOARP;
516
517 /* Set transmit buffer queue length */
518 dev->tx_queue_len = 10;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
520 /* Initialize socket buffers */
521 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
522
523 return 0;
524}
525
526/* Open network interface.
527 * o prevent module from unloading by incrementing use count
528 * o if link is disconnected then initiate connection
529 *
530 * Return 0 if O.k. or errno. */
531static int cycx_netdevice_open(struct net_device *dev)
532{
533 if (netif_running(dev))
534 return -EBUSY; /* only one open is allowed */
535
536 netif_start_queue(dev);
537 return 0;
538}
539
540/* Close network interface.
541 * o reset flags.
542 * o if there's no more open channels then disconnect physical link. */
543static int cycx_netdevice_stop(struct net_device *dev)
544{
545 struct cycx_x25_channel *chan = dev->priv;
546
547 netif_stop_queue(dev);
548
549 if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
550 cycx_x25_chan_disconnect(dev);
551
552 return 0;
553}
554
555/* Build media header.
556 * o encapsulate packet according to encapsulation type.
557 *
558 * The trick here is to put packet type (Ethertype) into 'protocol' field of
559 * the socket buffer, so that we don't forget it. If encapsulation fails,
560 * set skb->protocol to 0 and discard packet later.
561 *
562 * Return: media header length. */
563static int cycx_netdevice_hard_header(struct sk_buff *skb,
564 struct net_device *dev, u16 type,
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -0700565 const void *daddr, const void *saddr,
566 unsigned len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567{
Al Viro7fd71e52007-12-22 17:27:24 +0000568 skb->protocol = htons(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569
570 return dev->hard_header_len;
571}
572
573/* * Re-build media header.
574 * Return: 1 physical address resolved.
575 * 0 physical address not resolved */
576static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
577{
578 return 1;
579}
580
581/* Send a packet on a network interface.
582 * o set busy flag (marks start of the transmission).
583 * o check link state. If link is not up, then drop the packet.
584 * o check channel status. If it's down then initiate a call.
585 * o pass a packet to corresponding WAN device.
586 * o free socket buffer
587 *
588 * Return: 0 complete (socket buffer must be freed)
589 * non-0 packet may be re-transmitted (tbusy must be set)
590 *
591 * Notes:
592 * 1. This routine is called either by the protocol stack or by the "net
593 * bottom half" (with interrupts enabled).
594 * 2. Setting tbusy flag will inhibit further transmit requests from the
595 * protocol stack and can be used for flow control with protocol layer. */
596static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
597 struct net_device *dev)
598{
599 struct cycx_x25_channel *chan = dev->priv;
600 struct cycx_device *card = chan->card;
601
602 if (!chan->svc)
Al Viro7fd71e52007-12-22 17:27:24 +0000603 chan->protocol = ntohs(skb->protocol);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
605 if (card->wandev.state != WAN_CONNECTED)
606 ++chan->ifstats.tx_dropped;
607 else if (chan->svc && chan->protocol &&
Al Viro7fd71e52007-12-22 17:27:24 +0000608 chan->protocol != ntohs(skb->protocol)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 printk(KERN_INFO
610 "%s: unsupported Ethertype 0x%04X on interface %s!\n",
Al Viro7fd71e52007-12-22 17:27:24 +0000611 card->devname, ntohs(skb->protocol), dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 ++chan->ifstats.tx_errors;
613 } else if (chan->protocol == ETH_P_IP) {
614 switch (chan->state) {
615 case WAN_DISCONNECTED:
616 if (cycx_x25_chan_connect(dev)) {
617 netif_stop_queue(dev);
618 return -EBUSY;
619 }
620 /* fall thru */
621 case WAN_CONNECTED:
622 reset_timer(dev);
623 dev->trans_start = jiffies;
624 netif_stop_queue(dev);
625
626 if (cycx_x25_chan_send(dev, skb))
627 return -EBUSY;
628
629 break;
630 default:
631 ++chan->ifstats.tx_dropped;
632 ++card->wandev.stats.tx_dropped;
633 }
634 } else { /* chan->protocol == ETH_P_X25 */
635 switch (skb->data[0]) {
636 case 0: break;
637 case 1: /* Connect request */
638 cycx_x25_chan_connect(dev);
639 goto free_packet;
640 case 2: /* Disconnect request */
641 cycx_x25_chan_disconnect(dev);
642 goto free_packet;
643 default:
644 printk(KERN_INFO
645 "%s: unknown %d x25-iface request on %s!\n",
646 card->devname, skb->data[0], dev->name);
647 ++chan->ifstats.tx_errors;
648 goto free_packet;
649 }
650
651 skb_pull(skb, 1); /* Remove control byte */
652 reset_timer(dev);
653 dev->trans_start = jiffies;
654 netif_stop_queue(dev);
655
656 if (cycx_x25_chan_send(dev, skb)) {
657 /* prepare for future retransmissions */
658 skb_push(skb, 1);
659 return -EBUSY;
660 }
661 }
662
663free_packet:
664 dev_kfree_skb(skb);
665
666 return 0;
667}
668
669/* Get Ethernet-style interface statistics.
670 * Return a pointer to struct net_device_stats */
671static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
672{
673 struct cycx_x25_channel *chan = dev->priv;
674
675 return chan ? &chan->ifstats : NULL;
676}
677
678/* Interrupt Handlers */
679/* X.25 Interrupt Service Routine. */
680static void cycx_x25_irq_handler(struct cycx_device *card)
681{
682 struct cycx_x25_cmd cmd;
683 u16 z = 0;
684
685 card->in_isr = 1;
686 card->buff_int_mode_unbusy = 0;
687 cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
688
689 switch (cmd.command) {
690 case X25_DATA_INDICATION:
691 cycx_x25_irq_rx(card, &cmd);
692 break;
693 case X25_ACK_FROM_VC:
694 cycx_x25_irq_tx(card, &cmd);
695 break;
696 case X25_LOG:
697 cycx_x25_irq_log(card, &cmd);
698 break;
699 case X25_STATISTIC:
700 cycx_x25_irq_stat(card, &cmd);
701 break;
702 case X25_CONNECT_CONFIRM:
703 cycx_x25_irq_connect_confirm(card, &cmd);
704 break;
705 case X25_CONNECT_INDICATION:
706 cycx_x25_irq_connect(card, &cmd);
707 break;
708 case X25_DISCONNECT_INDICATION:
709 cycx_x25_irq_disconnect(card, &cmd);
710 break;
711 case X25_DISCONNECT_CONFIRM:
712 cycx_x25_irq_disconnect_confirm(card, &cmd);
713 break;
714 case X25_LINE_ON:
715 cycx_set_state(card, WAN_CONNECTED);
716 break;
717 case X25_LINE_OFF:
718 cycx_set_state(card, WAN_DISCONNECTED);
719 break;
720 default:
721 cycx_x25_irq_spurious(card, &cmd);
722 break;
723 }
724
725 cycx_poke(&card->hw, 0, &z, sizeof(z));
726 cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
727 card->in_isr = 0;
728}
729
730/* Transmit interrupt handler.
731 * o Release socket buffer
732 * o Clear 'tbusy' flag */
733static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
734{
735 struct net_device *dev;
736 struct wan_device *wandev = &card->wandev;
737 u8 lcn;
738
739 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
740
741 /* unbusy device and then dev_tint(); */
742 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
743 if (dev) {
744 card->buff_int_mode_unbusy = 1;
745 netif_wake_queue(dev);
746 } else
747 printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n",
748 card->devname, lcn);
749}
750
751/* Receive interrupt handler.
752 * This routine handles fragmented IP packets using M-bit according to the
753 * RFC1356.
754 * o map logical channel number to network interface.
755 * o allocate socket buffer or append received packet to the existing one.
756 * o if M-bit is reset (i.e. it's the last packet in a sequence) then
757 * decapsulate packet and pass socket buffer to the protocol stack.
758 *
759 * Notes:
760 * 1. When allocating a socket buffer, if M-bit is set then more data is
761 * coming and we have to allocate buffer for the maximum IP packet size
762 * expected on this channel.
763 * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
764 * socket buffers available) the whole packet sequence must be discarded. */
765static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
766{
767 struct wan_device *wandev = &card->wandev;
768 struct net_device *dev;
769 struct cycx_x25_channel *chan;
770 struct sk_buff *skb;
771 u8 bitm, lcn;
772 int pktlen = cmd->len - 5;
773
774 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
775 cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
776 bitm &= 0x10;
777
778 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
779 if (!dev) {
780 /* Invalid channel, discard packet */
781 printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
782 card->devname, lcn);
783 return;
784 }
785
786 chan = dev->priv;
787 reset_timer(dev);
788
789 if (chan->drop_sequence) {
790 if (!bitm)
791 chan->drop_sequence = 0;
792 else
793 return;
794 }
795
796 if ((skb = chan->rx_skb) == NULL) {
797 /* Allocate new socket buffer */
798 int bufsize = bitm ? dev->mtu : pktlen;
799
800 if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
801 bufsize +
802 dev->hard_header_len)) == NULL) {
803 printk(KERN_INFO "%s: no socket buffers available!\n",
804 card->devname);
805 chan->drop_sequence = 1;
806 ++chan->ifstats.rx_dropped;
807 return;
808 }
809
810 if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
811 /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
812 skb_put(skb, 1);
813
814 skb->dev = dev;
815 skb->protocol = htons(chan->protocol);
816 chan->rx_skb = skb;
817 }
818
819 if (skb_tailroom(skb) < pktlen) {
820 /* No room for the packet. Call off the whole thing! */
821 dev_kfree_skb_irq(skb);
822 chan->rx_skb = NULL;
823
824 if (bitm)
825 chan->drop_sequence = 1;
826
827 printk(KERN_INFO "%s: unexpectedly long packet sequence "
828 "on interface %s!\n", card->devname, dev->name);
829 ++chan->ifstats.rx_length_errors;
830 return;
831 }
832
833 /* Append packet to the socket buffer */
834 cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
835
836 if (bitm)
837 return; /* more data is coming */
838
839 chan->rx_skb = NULL; /* dequeue packet */
840
841 ++chan->ifstats.rx_packets;
842 chan->ifstats.rx_bytes += pktlen;
843
Arnaldo Carvalho de Melo459a98e2007-03-19 15:30:44 -0700844 skb_reset_mac_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 netif_rx(skb);
846 dev->last_rx = jiffies; /* timestamp */
847}
848
849/* Connect interrupt handler. */
850static void cycx_x25_irq_connect(struct cycx_device *card,
851 struct cycx_x25_cmd *cmd)
852{
853 struct wan_device *wandev = &card->wandev;
854 struct net_device *dev = NULL;
855 struct cycx_x25_channel *chan;
856 u8 d[32],
857 loc[24],
858 rem[24];
859 u8 lcn, sizeloc, sizerem;
860
861 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
862 cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
863 cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
864
865 sizerem = sizeloc >> 4;
866 sizeloc &= 0x0F;
867
868 loc[0] = rem[0] = '\0';
869
870 if (sizeloc)
871 nibble_to_byte(d, loc, sizeloc, 0);
872
873 if (sizerem)
874 nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
875
876 dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
877 __FUNCTION__, lcn, loc, rem);
878
879 dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
880 if (!dev) {
881 /* Invalid channel, discard packet */
882 printk(KERN_INFO "%s: connect not expected: remote %s!\n",
883 card->devname, rem);
884 return;
885 }
886
887 chan = dev->priv;
888 chan->lcn = lcn;
889 cycx_x25_connect_response(card, chan);
890 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
891}
892
893/* Connect confirm interrupt handler. */
894static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
895 struct cycx_x25_cmd *cmd)
896{
897 struct wan_device *wandev = &card->wandev;
898 struct net_device *dev;
899 struct cycx_x25_channel *chan;
900 u8 lcn, key;
901
902 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
903 cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
904 dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
905 card->devname, __FUNCTION__, lcn, key);
906
907 dev = cycx_x25_get_dev_by_lcn(wandev, -key);
908 if (!dev) {
909 /* Invalid channel, discard packet */
910 clear_bit(--key, (void*)&card->u.x.connection_keys);
911 printk(KERN_INFO "%s: connect confirm not expected: lcn %d, "
912 "key=%d!\n", card->devname, lcn, key);
913 return;
914 }
915
916 clear_bit(--key, (void*)&card->u.x.connection_keys);
917 chan = dev->priv;
918 chan->lcn = lcn;
919 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
920}
921
922/* Disconnect confirm interrupt handler. */
923static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
924 struct cycx_x25_cmd *cmd)
925{
926 struct wan_device *wandev = &card->wandev;
927 struct net_device *dev;
928 u8 lcn;
929
930 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
931 dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
932 card->devname, __FUNCTION__, lcn);
933 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
934 if (!dev) {
935 /* Invalid channel, discard packet */
936 printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n",
937 card->devname, lcn);
938 return;
939 }
940
941 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
942}
943
944/* disconnect interrupt handler. */
945static void cycx_x25_irq_disconnect(struct cycx_device *card,
946 struct cycx_x25_cmd *cmd)
947{
948 struct wan_device *wandev = &card->wandev;
949 struct net_device *dev;
950 u8 lcn;
951
952 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
953 dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn);
954
955 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
956 if (dev) {
957 struct cycx_x25_channel *chan = dev->priv;
958
959 cycx_x25_disconnect_response(card, chan->link, lcn);
960 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
961 } else
962 cycx_x25_disconnect_response(card, 0, lcn);
963}
964
965/* LOG interrupt handler. */
966static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd)
967{
968#if CYCLOMX_X25_DEBUG
969 char bf[20];
970 u16 size, toread, link, msg_code;
971 u8 code, routine;
972
973 cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
974 cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
975 cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
976 /* at most 20 bytes are available... thanks to Daniela :) */
977 toread = size < 20 ? size : 20;
978 cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
979 cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
980 cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
981
982 printk(KERN_INFO "cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n");
983 printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf);
984 printk(KERN_INFO "Log message code=0x%X\n", msg_code);
985 printk(KERN_INFO "Link=%d\n", link);
986 printk(KERN_INFO "log code=0x%X\n", code);
987 printk(KERN_INFO "log routine=0x%X\n", routine);
988 printk(KERN_INFO "Message size=%d\n", size);
989 hex_dump("Message", bf, toread);
990#endif
991}
992
993/* STATISTIC interrupt handler. */
994static void cycx_x25_irq_stat(struct cycx_device *card,
995 struct cycx_x25_cmd *cmd)
996{
997 cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
998 sizeof(card->u.x.stats));
999 hex_dump("cycx_x25_irq_stat", (unsigned char*)&card->u.x.stats,
1000 sizeof(card->u.x.stats));
1001 cycx_x25_dump_stats(&card->u.x.stats);
1002 wake_up_interruptible(&card->wait_stats);
1003}
1004
1005/* Spurious interrupt handler.
1006 * o print a warning
1007 * If number of spurious interrupts exceeded some limit, then ??? */
1008static void cycx_x25_irq_spurious(struct cycx_device *card,
1009 struct cycx_x25_cmd *cmd)
1010{
1011 printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n",
1012 card->devname, cmd->command);
1013}
1014#ifdef CYCLOMX_X25_DEBUG
1015static void hex_dump(char *msg, unsigned char *p, int len)
1016{
1017 unsigned char hex[1024],
1018 * phex = hex;
1019
1020 if (len >= (sizeof(hex) / 2))
1021 len = (sizeof(hex) / 2) - 1;
1022
1023 while (len--) {
1024 sprintf(phex, "%02x", *p++);
1025 phex += 2;
1026 }
1027
1028 printk(KERN_INFO "%s: %s\n", msg, hex);
1029}
1030#endif
1031
1032/* Cyclom 2X Firmware-Specific Functions */
1033/* Exec X.25 command. */
1034static int x25_exec(struct cycx_device *card, int command, int link,
1035 void *d1, int len1, void *d2, int len2)
1036{
1037 struct cycx_x25_cmd c;
1038 unsigned long flags;
1039 u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
1040 u8 retry = CYCX_X25_MAX_CMD_RETRY;
1041 int err = 0;
1042
1043 c.command = command;
1044 c.link = link;
1045 c.len = len1 + len2;
1046
1047 spin_lock_irqsave(&card->u.x.lock, flags);
1048
1049 /* write command */
1050 cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
1051
1052 /* write X.25 data */
1053 if (d1) {
1054 cycx_poke(&card->hw, addr, d1, len1);
1055
1056 if (d2) {
1057 if (len2 > 254) {
1058 u32 addr1 = 0xA00 + 0x400 * link;
1059
1060 cycx_poke(&card->hw, addr + len1, d2, 249);
1061 cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
1062 len2 - 249);
1063 } else
1064 cycx_poke(&card->hw, addr + len1, d2, len2);
1065 }
1066 }
1067
1068 /* generate interruption, executing command */
1069 cycx_intr(&card->hw);
1070
1071 /* wait till card->mbox == 0 */
1072 do {
1073 err = cycx_exec(card->mbox);
1074 } while (retry-- && err);
1075
1076 spin_unlock_irqrestore(&card->u.x.lock, flags);
1077
1078 return err;
1079}
1080
1081/* Configure adapter. */
1082static int cycx_x25_configure(struct cycx_device *card,
1083 struct cycx_x25_config *conf)
1084{
1085 struct {
1086 u16 nlinks;
1087 struct cycx_x25_config conf[2];
1088 } x25_cmd_conf;
1089
1090 memset(&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1091 x25_cmd_conf.nlinks = 2;
1092 x25_cmd_conf.conf[0] = *conf;
1093 /* FIXME: we need to find a way in the wanrouter framework
1094 to configure the second link, for now lets use it
1095 with the same config from the first link, fixing
1096 the interface type to RS232, the speed in 38400 and
1097 the clock to external */
1098 x25_cmd_conf.conf[1] = *conf;
1099 x25_cmd_conf.conf[1].link = 1;
1100 x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1101 x25_cmd_conf.conf[1].clock = 8;
1102 x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1103
1104 cycx_x25_dump_config(&x25_cmd_conf.conf[0]);
1105 cycx_x25_dump_config(&x25_cmd_conf.conf[1]);
1106
1107 return x25_exec(card, X25_CONFIG, 0,
1108 &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1109}
1110
1111/* Get protocol statistics. */
1112static int cycx_x25_get_stats(struct cycx_device *card)
1113{
1114 /* the firmware expects 20 in the size field!!!
1115 thanks to Daniela */
1116 int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1117
1118 if (err)
1119 return err;
1120
1121 interruptible_sleep_on(&card->wait_stats);
1122
1123 if (signal_pending(current))
1124 return -EINTR;
1125
1126 card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1127 card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1128 card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1129 card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1130 card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1131 card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1132 card->wandev.stats.rx_dropped = 0; /* not available from fw */
1133 card->wandev.stats.rx_errors = 0; /* not available from fw */
1134 card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1135 card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1136 card->wandev.stats.tx_dropped = 0; /* not available from fw */
1137 card->wandev.stats.collisions = 0; /* not available from fw */
1138 card->wandev.stats.tx_errors = 0; /* not available from fw */
1139
1140 cycx_x25_dump_devs(&card->wandev);
1141
1142 return 0;
1143}
1144
1145/* return the number of nibbles */
1146static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1147{
1148 int i = 0;
1149
1150 if (*nibble && *s) {
1151 d[i] |= *s++ - '0';
1152 *nibble = 0;
1153 ++i;
1154 }
1155
1156 while (*s) {
1157 d[i] = (*s - '0') << 4;
1158 if (*(s + 1))
1159 d[i] |= *(s + 1) - '0';
1160 else {
1161 *nibble = 1;
1162 break;
1163 }
1164 ++i;
1165 s += 2;
1166 }
1167
1168 return i;
1169}
1170
1171static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1172{
1173 if (nibble) {
1174 *d++ = '0' + (*s++ & 0x0F);
1175 --len;
1176 }
1177
1178 while (len) {
1179 *d++ = '0' + (*s >> 4);
1180
1181 if (--len) {
1182 *d++ = '0' + (*s & 0x0F);
1183 --len;
1184 } else break;
1185
1186 ++s;
1187 }
1188
1189 *d = '\0';
1190}
1191
1192/* Place X.25 call. */
1193static int x25_place_call(struct cycx_device *card,
1194 struct cycx_x25_channel *chan)
1195{
1196 int err = 0,
1197 len;
1198 char d[64],
1199 nibble = 0,
1200 mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1201 remotelen = strlen(chan->addr);
1202 u8 key;
1203
1204 if (card->u.x.connection_keys == ~0U) {
1205 printk(KERN_INFO "%s: too many simultaneous connection "
1206 "requests!\n", card->devname);
1207 return -EAGAIN;
1208 }
1209
1210 key = ffz(card->u.x.connection_keys);
1211 set_bit(key, (void*)&card->u.x.connection_keys);
1212 ++key;
1213 dprintk(1, KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1214 memset(d, 0, sizeof(d));
1215 d[1] = key; /* user key */
1216 d[2] = 0x10;
1217 d[4] = 0x0B;
1218
1219 len = byte_to_nibble(chan->addr, d + 6, &nibble);
1220
1221 if (chan->local_addr)
1222 len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
1223
1224 if (nibble)
1225 ++len;
1226
1227 d[5] = mylen << 4 | remotelen;
1228 d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
1229
1230 if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1231 &d, 7 + len + 1, NULL, 0)) != 0)
1232 clear_bit(--key, (void*)&card->u.x.connection_keys);
1233 else
1234 chan->lcn = -key;
1235
1236 return err;
1237}
1238
1239/* Place X.25 CONNECT RESPONSE. */
1240static int cycx_x25_connect_response(struct cycx_device *card,
1241 struct cycx_x25_channel *chan)
1242{
1243 u8 d[8];
1244
1245 memset(d, 0, sizeof(d));
1246 d[0] = d[3] = chan->lcn;
1247 d[2] = 0x10;
1248 d[4] = 0x0F;
1249 d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
1250
1251 return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
1252}
1253
1254/* Place X.25 DISCONNECT RESPONSE. */
1255static int cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
1256 u8 lcn)
1257{
1258 char d[5];
1259
1260 memset(d, 0, sizeof(d));
1261 d[0] = d[3] = lcn;
1262 d[2] = 0x10;
1263 d[4] = 0x17;
1264
1265 return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
1266}
1267
1268/* Clear X.25 call. */
1269static int x25_clear_call(struct cycx_device *card, u8 link, u8 lcn, u8 cause,
1270 u8 diagn)
1271{
1272 u8 d[7];
1273
1274 memset(d, 0, sizeof(d));
1275 d[0] = d[3] = lcn;
1276 d[2] = 0x10;
1277 d[4] = 0x13;
1278 d[5] = cause;
1279 d[6] = diagn;
1280
1281 return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
1282}
1283
1284/* Send X.25 data packet. */
1285static int cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
1286 int len, void *buf)
1287{
1288 u8 d[] = "?\xFF\x10??";
1289
1290 d[0] = d[3] = lcn;
1291 d[4] = bitm;
1292
1293 return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
1294}
1295
1296/* Miscellaneous */
1297/* Find network device by its channel number. */
1298static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
1299 s16 lcn)
1300{
1301 struct net_device *dev = wandev->dev;
1302 struct cycx_x25_channel *chan;
1303
1304 while (dev) {
1305 chan = (struct cycx_x25_channel*)dev->priv;
1306
1307 if (chan->lcn == lcn)
1308 break;
1309 dev = chan->slave;
1310 }
1311 return dev;
1312}
1313
1314/* Find network device by its remote dte address. */
1315static struct net_device *
1316 cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte)
1317{
1318 struct net_device *dev = wandev->dev;
1319 struct cycx_x25_channel *chan;
1320
1321 while (dev) {
1322 chan = (struct cycx_x25_channel*)dev->priv;
1323
1324 if (!strcmp(chan->addr, dte))
1325 break;
1326 dev = chan->slave;
1327 }
1328 return dev;
1329}
1330
1331/* Initiate connection on the logical channel.
1332 * o for PVC we just get channel configuration
1333 * o for SVCs place an X.25 call
1334 *
1335 * Return: 0 connected
1336 * >0 connection in progress
1337 * <0 failure */
1338static int cycx_x25_chan_connect(struct net_device *dev)
1339{
1340 struct cycx_x25_channel *chan = dev->priv;
1341 struct cycx_device *card = chan->card;
1342
1343 if (chan->svc) {
1344 if (!chan->addr[0])
1345 return -EINVAL; /* no destination address */
1346
1347 dprintk(1, KERN_INFO "%s: placing X.25 call to %s...\n",
1348 card->devname, chan->addr);
1349
1350 if (x25_place_call(card, chan))
1351 return -EIO;
1352
1353 cycx_x25_set_chan_state(dev, WAN_CONNECTING);
1354 return 1;
1355 } else
1356 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
1357
1358 return 0;
1359}
1360
1361/* Disconnect logical channel.
1362 * o if SVC then clear X.25 call */
1363static void cycx_x25_chan_disconnect(struct net_device *dev)
1364{
1365 struct cycx_x25_channel *chan = dev->priv;
1366
1367 if (chan->svc) {
1368 x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1369 cycx_x25_set_chan_state(dev, WAN_DISCONNECTING);
1370 } else
1371 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
1372}
1373
1374/* Called by kernel timer */
1375static void cycx_x25_chan_timer(unsigned long d)
1376{
1377 struct net_device *dev = (struct net_device *)d;
1378 struct cycx_x25_channel *chan = dev->priv;
1379
1380 if (chan->state == WAN_CONNECTED)
1381 cycx_x25_chan_disconnect(dev);
1382 else
1383 printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
1384 chan->card->devname, __FUNCTION__, dev->name);
1385}
1386
1387/* Set logical channel state. */
1388static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
1389{
1390 struct cycx_x25_channel *chan = dev->priv;
1391 struct cycx_device *card = chan->card;
1392 unsigned long flags;
1393 char *string_state = NULL;
1394
1395 spin_lock_irqsave(&card->lock, flags);
1396
1397 if (chan->state != state) {
1398 if (chan->svc && chan->state == WAN_CONNECTED)
1399 del_timer(&chan->timer);
1400
1401 switch (state) {
1402 case WAN_CONNECTED:
1403 string_state = "connected!";
Al Viro7fd71e52007-12-22 17:27:24 +00001404 *(__be16*)dev->dev_addr = htons(chan->lcn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 netif_wake_queue(dev);
1406 reset_timer(dev);
1407
1408 if (chan->protocol == ETH_P_X25)
1409 cycx_x25_chan_send_event(dev, 1);
1410
1411 break;
1412 case WAN_CONNECTING:
1413 string_state = "connecting...";
1414 break;
1415 case WAN_DISCONNECTING:
1416 string_state = "disconnecting...";
1417 break;
1418 case WAN_DISCONNECTED:
1419 string_state = "disconnected!";
1420
1421 if (chan->svc) {
1422 *(unsigned short*)dev->dev_addr = 0;
1423 chan->lcn = 0;
1424 }
1425
1426 if (chan->protocol == ETH_P_X25)
1427 cycx_x25_chan_send_event(dev, 2);
1428
1429 netif_wake_queue(dev);
1430 break;
1431 }
1432
1433 printk(KERN_INFO "%s: interface %s %s\n", card->devname,
1434 dev->name, string_state);
1435 chan->state = state;
1436 }
1437
1438 spin_unlock_irqrestore(&card->lock, flags);
1439}
1440
1441/* Send packet on a logical channel.
1442 * When this function is called, tx_skb field of the channel data space
1443 * points to the transmit socket buffer. When transmission is complete,
1444 * release socket buffer and reset 'tbusy' flag.
1445 *
1446 * Return: 0 - transmission complete
1447 * 1 - busy
1448 *
1449 * Notes:
1450 * 1. If packet length is greater than MTU for this channel, we'll fragment
1451 * the packet into 'complete sequence' using M-bit.
1452 * 2. When transmission is complete, an event notification should be issued
1453 * to the router. */
1454static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
1455{
1456 struct cycx_x25_channel *chan = dev->priv;
1457 struct cycx_device *card = chan->card;
1458 int bitm = 0; /* final packet */
1459 unsigned len = skb->len;
1460
1461 if (skb->len > card->wandev.mtu) {
1462 len = card->wandev.mtu;
1463 bitm = 0x10; /* set M-bit (more data) */
1464 }
1465
1466 if (cycx_x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1467 return 1;
1468
1469 if (bitm) {
1470 skb_pull(skb, len);
1471 return 1;
1472 }
1473
1474 ++chan->ifstats.tx_packets;
1475 chan->ifstats.tx_bytes += len;
1476
1477 return 0;
1478}
1479
1480/* Send event (connection, disconnection, etc) to X.25 socket layer */
1481
1482static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
1483{
1484 struct sk_buff *skb;
1485 unsigned char *ptr;
1486
1487 if ((skb = dev_alloc_skb(1)) == NULL) {
1488 printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
1489 return;
1490 }
1491
1492 ptr = skb_put(skb, 1);
1493 *ptr = event;
1494
1495 skb->protocol = x25_type_trans(skb, dev);
1496 netif_rx(skb);
1497 dev->last_rx = jiffies; /* timestamp */
1498}
1499
1500/* Convert line speed in bps to a number used by cyclom 2x code. */
1501static u8 bps_to_speed_code(u32 bps)
1502{
1503 u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1504
1505 if (bps >= 512000) number = 8;
1506 else if (bps >= 256000) number = 7;
1507 else if (bps >= 64000) number = 6;
1508 else if (bps >= 38400) number = 5;
1509 else if (bps >= 19200) number = 4;
1510 else if (bps >= 9600) number = 3;
1511 else if (bps >= 4800) number = 2;
1512 else if (bps >= 2400) number = 1;
1513
1514 return number;
1515}
1516
1517/* log base 2 */
1518static u8 cycx_log2(u32 n)
1519{
1520 u8 log = 0;
1521
1522 if (!n)
1523 return 0;
1524
1525 while (n > 1) {
1526 n >>= 1;
1527 ++log;
1528 }
1529
1530 return log;
1531}
1532
1533/* Convert decimal string to unsigned integer.
1534 * If len != 0 then only 'len' characters of the string are converted. */
1535static unsigned dec_to_uint(u8 *str, int len)
1536{
1537 unsigned val = 0;
1538
1539 if (!len)
1540 len = strlen(str);
1541
Tobias Klauser8e18d1f2005-09-10 14:45:00 -07001542 for (; len && isdigit(*str); ++str, --len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 val = (val * 10) + (*str - (unsigned) '0');
1544
1545 return val;
1546}
1547
1548static void reset_timer(struct net_device *dev)
1549{
1550 struct cycx_x25_channel *chan = dev->priv;
1551
1552 if (chan->svc)
1553 mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
1554}
1555#ifdef CYCLOMX_X25_DEBUG
1556static void cycx_x25_dump_config(struct cycx_x25_config *conf)
1557{
1558 printk(KERN_INFO "X.25 configuration\n");
1559 printk(KERN_INFO "-----------------\n");
1560 printk(KERN_INFO "link number=%d\n", conf->link);
1561 printk(KERN_INFO "line speed=%d\n", conf->speed);
1562 printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1563 printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1564 printk(KERN_INFO "level 2 window=%d\n", conf->n2win);
1565 printk(KERN_INFO "level 3 window=%d\n", conf->n3win);
1566 printk(KERN_INFO "# logical channels=%d\n", conf->nvc);
1567 printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1568 printk(KERN_INFO "my address=%d\n", conf->locaddr);
1569 printk(KERN_INFO "remote address=%d\n", conf->remaddr);
1570 printk(KERN_INFO "t1=%d seconds\n", conf->t1);
1571 printk(KERN_INFO "t2=%d seconds\n", conf->t2);
1572 printk(KERN_INFO "t21=%d seconds\n", conf->t21);
1573 printk(KERN_INFO "# PVCs=%d\n", conf->npvc);
1574 printk(KERN_INFO "t23=%d seconds\n", conf->t23);
1575 printk(KERN_INFO "flags=0x%x\n", conf->flags);
1576}
1577
1578static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
1579{
1580 printk(KERN_INFO "X.25 statistics\n");
1581 printk(KERN_INFO "--------------\n");
1582 printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1583 printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1584 printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1585 printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1586 printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1587 printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1588 printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1589 printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1590 printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1591 printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1592}
1593
1594static void cycx_x25_dump_devs(struct wan_device *wandev)
1595{
1596 struct net_device *dev = wandev->dev;
1597
1598 printk(KERN_INFO "X.25 dev states\n");
1599 printk(KERN_INFO "name: addr: txoff: protocol:\n");
1600 printk(KERN_INFO "---------------------------------------\n");
1601
1602 while(dev) {
1603 struct cycx_x25_channel *chan = dev->priv;
1604
1605 printk(KERN_INFO "%-5.5s %-15.15s %d ETH_P_%s\n",
1606 chan->name, chan->addr, netif_queue_stopped(dev),
1607 chan->protocol == ETH_P_IP ? "IP" : "X25");
1608 dev = chan->slave;
1609 }
1610}
1611
1612#endif /* CYCLOMX_X25_DEBUG */
1613/* End */