Import 2.3.10pre5
[davej-history.git] / drivers / net / cycx_x25.c
blobd6fbe07c35dcc8aca423c7ab910bfec423319672
1 /*
2 * cycx_x25.c CYCLOM X Multiprotocol WAN Link Driver. X.25 module.
4 * Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5 * Copyright: (c) 1998, 1999 Arnaldo Carvalho de Melo
7 * Based on sdla_x25.c by Gene Kozin <genek@compuserve.com>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 * ============================================================================
14 * 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated
15 * if_send simplified
16 * 1999/05/25 acme fixed t1, t2, t21 & t23 configuration
17 * use spinlocks instead of cli/sti in some points
18 * 1999/05/24 acme finished the x25_get_stat function
19 * 1999/05/23 acme dev->type = ARPHRD_X25 (tcpdump only works,
20 * AFAIT, with ARPHRD_ETHER). This seems to be
21 * needed to use socket(AF_X25)...
22 * Now the config file must specify a peer media
23 * address for svc channes over a crossover cable.
24 * Removed hold_timeout from x25_channel_t,
25 * not used.
26 * A little enhancement in the DEBUG processing
27 * 1999/05/22 acme go to DISCONNECTED in disconnect_confirm_intr,
28 * instead of chan_disc.
29 * 1999/05/16 marcelo fixed timer initialization in SVCs
30 * 1999/01/05 acme x25_configure now get (most of) all
31 * parameters...
32 * 1999/01/05 acme pktlen now (correctly) uses log2 (value
33 * configured)
34 * 1999/01/03 acme judicious use of data types (u8, u16, u32, etc)
35 * 1999/01/03 acme cyx_isr: reset dpmbase to acknowledge
36 * indication (interrupt from cyclom 2x)
37 * 1999/01/02 acme cyx_isr: first hackings...
38 * 1999/01/0203 acme when initializing an array don't give less
39 * elements than declared...
40 * example: char send_cmd[6] = "?\xFF\x10";
41 * you'll gonna lose a couple hours, 'cause your
42 * brain won't admit that there's an error in the
43 * above declaration... the side effect is that
44 * memset is put into the unresolved symbols
45 * instead of using the inline memset functions...
46 * 1999/01/02 acme began chan_connect, chan_send, x25_send
47 * Dec 31, 1998 Arnaldo x25_configure
48 * this code can be compiled as non module
49 * Dec 27, 1998 Arnaldo code cleanup
50 * IPX code wiped out! let's decrease code
51 * complexity for now, remember: I'm learning! :)
52 * bps_to_speed_code OK
53 * Dec 26, 1998 Arnaldo Minimal debug code cleanup
54 * Aug 08, 1998 Arnaldo Initial version.
56 #define CYCLOMX_X25_DEBUG 1
58 #include <linux/version.h>
59 #include <linux/kernel.h> /* printk(), and other useful stuff */
60 #include <linux/stddef.h> /* offsetof(), etc. */
61 #include <linux/errno.h> /* return codes */
62 #include <linux/string.h> /* inline memset(), etc. */
63 #include <linux/malloc.h> /* kmalloc(), kfree() */
64 #include <linux/wanrouter.h> /* WAN router definitions */
65 #include <asm/byteorder.h> /* htons(), etc. */
66 #include <linux/if_arp.h> /* ARPHRD_X25 */
67 #include <linux/cyclomx.h> /* CYCLOM X common user API definitions */
68 #include <linux/cycx_x25.h> /* X.25 firmware API definitions */
70 /* Defines & Macros */
71 #define MAX_CMD_RETRY 5
72 #define X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
73 #define OUT_INTR 1
74 #define IN_INTR 0
76 /* Data Structures */
77 /* This is an extention of the 'struct device' we create for each network
78 interface to keep the rest of X.25 channel-specific data. */
79 typedef struct x25_channel {
80 char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
81 char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
82 char *local_addr; /* local media address, ASCIIZ -
83 svc thru crossover cable */
84 s16 lcn; /* logical channel number/conn.req.key*/
85 u8 link;
86 struct timer_list timer; /* timer used for svc channel disc. */
87 spinlock_t lock;
88 u16 protocol; /* ethertype, 0 - multiplexed */
89 u8 svc; /* 0 - permanent, 1 - switched */
90 u8 state; /* channel state */
91 u8 drop_sequence; /* mark sequence for dropping */
92 u32 idle_tmout; /* sec, before disconnecting */
93 struct sk_buff *rx_skb; /* receive socket buffer */
94 cycx_t *card; /* -> owner */
95 struct enet_statistics ifstats; /* interface statistics */
96 } x25_channel_t;
98 /* Function Prototypes */
99 /* WAN link driver entry points. These are called by the WAN router module. */
100 static int update (wan_device_t *wandev),
101 new_if (wan_device_t *wandev, struct device *dev,wanif_conf_t *conf),
102 del_if (wan_device_t *wandev, struct device *dev);
104 /* Network device interface */
105 static int if_init (struct device *dev),
106 if_open (struct device *dev),
107 if_close (struct device *dev),
108 if_header (struct sk_buff *skb, struct device *dev,
109 u16 type, void *daddr, void *saddr, unsigned len),
110 if_rebuild_hdr (struct sk_buff *skb),
111 if_send (struct sk_buff *skb, struct device *dev);
113 static struct net_device_stats * if_stats (struct device *dev);
115 /* Interrupt handlers */
116 static void cyx_isr (cycx_t *card),
117 tx_intr (cycx_t *card, TX25Cmd *cmd),
118 rx_intr (cycx_t *card, TX25Cmd *cmd),
119 log_intr (cycx_t *card, TX25Cmd *cmd),
120 stat_intr (cycx_t *card, TX25Cmd *cmd),
121 connect_confirm_intr (cycx_t *card, TX25Cmd *cmd),
122 disconnect_confirm_intr (cycx_t *card, TX25Cmd *cmd),
123 connect_intr (cycx_t *card, TX25Cmd *cmd),
124 disconnect_intr (cycx_t *card, TX25Cmd *cmd),
125 spur_intr (cycx_t *card, TX25Cmd *cmd);
127 /* X.25 firmware interface functions */
128 static int x25_configure (cycx_t *card, TX25Config *conf),
129 x25_get_stats (cycx_t *card),
130 x25_send (cycx_t *card, u8 link, u8 lcn, u8 bitm, int len,void *buf),
131 x25_connect_response (cycx_t *card, x25_channel_t *chan),
132 x25_disconnect_response (cycx_t *card, u8 link, u8 lcn);
134 /* Miscellaneous functions */
135 static int chan_connect (struct device *dev),
136 chan_send (struct device *dev, struct sk_buff *skb);
138 static void set_chan_state (struct device *dev, u8 state, u8 outside_intr),
139 nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble),
140 reset_timer (struct device *dev),
141 chan_disc (struct device *dev),
142 chan_timer (unsigned long data);
144 static u8 bps_to_speed_code (u32 bps);
145 static u8 log2 (u32 n);
147 static unsigned dec_to_uint (u8 *str, int len);
149 static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn);
150 static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte);
152 #ifdef CYCLOMX_X25_DEBUG
153 static void hex_dump(char *msg, unsigned char *p, int len);
154 static void x25_dump_config(TX25Config *conf);
155 static void x25_dump_stats(TX25Stats *stats);
156 static void x25_dump_devs(wan_device_t *wandev);
157 #define dprintk(format, a...) printk(format, ##a)
158 #else
159 #define hex_dump(msg, p, len)
160 #define x25_dump_config(conf)
161 #define x25_dump_stats(stats)
162 #define x25_dump_devs(wandev)
163 #define dprintk(format, a...)
164 #endif
165 /* Public Functions */
167 /* X.25 Protocol Initialization routine.
169 * This routine is called by the main CYCLOM X module during setup. At this
170 * point adapter is completely initialized and X.25 firmware is running.
171 * o read firmware version (to make sure it's alive)
172 * o configure adapter
173 * o initialize protocol-specific fields of the adapter data space.
175 * Return: 0 o.k.
176 * < 0 failure. */
177 int cyx_init (cycx_t *card, wandev_conf_t *conf)
179 TX25Config cfg;
181 /* Verify configuration ID */
182 if (conf->config_id != WANCONFIG_X25) {
183 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
184 card->devname, conf->config_id);
185 return -EINVAL;
188 /* Initialize protocol-specific fields */
189 card->mbox = card->hw.dpmbase + X25_MBOX_OFFS;
190 card->u.x.critical = 0; /* critical section flag */
191 card->u.x.connection_keys = 0;
193 /* Configure adapter. Here we set resonable defaults, then parse
194 * device configuration structure and set configuration options.
195 * Most configuration options are verified and corrected (if
196 * necessary) since we can't rely on the adapter to do so and don't
197 * want it to fail either. */
198 memset(&cfg, 0, sizeof(cfg));
199 cfg.link = 0;
200 cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
201 cfg.speed = bps_to_speed_code(conf->bps);
202 cfg.n3win = 7;
203 cfg.n2win = 2;
204 cfg.n2 = 5;
205 cfg.nvc = 1;
206 cfg.npvc = 1;
207 cfg.flags = 0x02; /* default = V35 */
208 cfg.t1 = 10; /* line carrier timeout */
209 cfg.t2 = 29; /* tx timeout */
210 cfg.t21 = 180; /* CALL timeout */
211 cfg.t23 = 180; /* CLEAR timeout */
213 /* adjust MTU */
214 if (!conf->mtu || conf->mtu >= 512)
215 card->wandev.mtu = 512;
216 else if (conf->mtu >= 256)
217 card->wandev.mtu = 256;
218 else if (conf->mtu >= 128)
219 card->wandev.mtu = 128;
220 else
221 card->wandev.mtu = 64;
223 cfg.pktlen = log2(card->wandev.mtu);
225 if (conf->station == WANOPT_DTE) {
226 cfg.locaddr = 3; /* DTE */
227 cfg.remaddr = 1; /* DCE */
228 } else {
229 cfg.locaddr = 1; /* DCE */
230 cfg.remaddr = 3; /* DTE */
233 if (conf->interface == WANOPT_RS232)
234 cfg.flags = 0; /* FIXME just reset the 2nd bit */
236 if (conf->u.x25.hi_pvc) {
237 card->u.x.hi_pvc = min(conf->u.x25.hi_pvc, 4095);
238 card->u.x.lo_pvc = min(conf->u.x25.lo_pvc, card->u.x.hi_pvc);
241 if (conf->u.x25.hi_svc) {
242 card->u.x.hi_svc = min(conf->u.x25.hi_svc, 4095);
243 card->u.x.lo_svc = min(conf->u.x25.lo_svc, card->u.x.hi_svc);
246 if (card->u.x.lo_pvc == 255)
247 cfg.npvc = 0;
248 else
249 cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
251 cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
253 if (conf->u.x25.hdlc_window)
254 cfg.n2win = min(conf->u.x25.hdlc_window, 7);
256 if (conf->u.x25.pkt_window)
257 cfg.n3win = min(conf->u.x25.pkt_window, 7);
259 if (conf->u.x25.t1)
260 cfg.t1 = min(conf->u.x25.t1, 30);
262 if (conf->u.x25.t2)
263 cfg.t2 = min(conf->u.x25.t2, 30);
265 if (conf->u.x25.t11_t21)
266 cfg.t21 = min(conf->u.x25.t11_t21, 30);
268 if (conf->u.x25.t13_t23)
269 cfg.t23 = min(conf->u.x25.t13_t23, 30);
271 if (conf->u.x25.n2)
272 cfg.n2 = min(conf->u.x25.n2, 30);
274 /* initialize adapter */
275 if (x25_configure(card, &cfg))
276 return -EIO;
278 /* Initialize protocol-specific fields of adapter data space */
279 card->wandev.bps = conf->bps;
280 card->wandev.interface = conf->interface;
281 card->wandev.clocking = conf->clocking;
282 card->wandev.station = conf->station;
283 card->isr = &cyx_isr;
284 card->exec = NULL;
285 card->wandev.update = &update;
286 card->wandev.new_if = &new_if;
287 card->wandev.del_if = &del_if;
288 card->wandev.state = WAN_DISCONNECTED;
289 card->wandev.enable_tx_int = card->irq_dis_if_send_count = 0;
290 return 0;
293 /* WAN Device Driver Entry Points */
294 /* Update device status & statistics. */
295 static int update (wan_device_t *wandev)
297 /* sanity checks */
298 if (!wandev || !wandev->private)
299 return -EFAULT;
301 if (wandev->state == WAN_UNCONFIGURED)
302 return -ENODEV;
304 x25_get_stats(wandev->private);
305 return 0;
308 /* Create new logical channel.
309 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
310 * handled.
311 * o parse media- and hardware-specific configuration
312 * o make sure that a new channel can be created
313 * o allocate resources, if necessary
314 * o prepare network device structure for registaration.
316 * Return: 0 o.k.
317 * < 0 failure (channel will not be created) */
318 static int new_if (wan_device_t *wandev, struct device *dev, wanif_conf_t *conf)
320 cycx_t *card = wandev->private;
321 x25_channel_t *chan;
322 int err = 0;
324 if (conf->name[0] == '\0' || strlen(conf->name) > WAN_IFNAME_SZ) {
325 printk(KERN_INFO "%s: invalid interface name!\n",card->devname);
326 return -EINVAL;
329 /* allocate and initialize private data */
330 if ((chan = kmalloc(sizeof(x25_channel_t), GFP_KERNEL)) == NULL)
331 return -ENOMEM;
333 memset(chan, 0, sizeof(x25_channel_t));
334 strcpy(chan->name, conf->name);
335 chan->card = card;
336 chan->link = conf->port;
337 chan->protocol = ETH_P_IP;
338 chan->rx_skb = NULL;
339 /* only used in svc connected thru crossover cable */
340 chan->local_addr = NULL;
341 chan->lock = SPIN_LOCK_UNLOCKED;
343 if (conf->addr[0] == '@') { /* SVC */
344 int local_len = strlen(conf->local_addr);
346 if (local_len) {
347 if (local_len > WAN_ADDRESS_SZ) {
348 printk(KERN_ERR "%s: %s local addr too long!\n",
349 wandev->name, chan->name);
350 kfree(chan);
351 return -EINVAL;
352 } else if ((chan->local_addr = kmalloc(local_len + 1,
353 GFP_KERNEL)) == NULL) {
354 kfree(chan);
355 return ENOMEM;
358 strncpy(chan->local_addr, conf->local_addr,
359 WAN_ADDRESS_SZ);
362 chan->svc = 1;
363 strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
364 init_timer(&chan->timer);
365 chan->timer.function = chan_timer;
366 chan->timer.data = (unsigned long) dev;
368 /* Set channel timeouts (default if not specified) */
369 chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
370 } else if (is_digit(conf->addr[0])) { /* PVC */
371 s16 lcn = dec_to_uint(conf->addr, 0);
373 if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
374 chan->lcn = lcn;
375 else {
376 printk(KERN_ERR
377 "%s: PVC %u is out of range on interface %s!\n",
378 wandev->name, lcn, chan->name);
379 err = -EINVAL;
381 } else {
382 printk(KERN_ERR "%s: invalid media address on interface %s!\n",
383 wandev->name, chan->name);
384 err = -EINVAL;
387 if (err) {
388 if (chan->local_addr)
389 kfree(chan->local_addr);
390 kfree(chan);
391 return err;
394 /* prepare network device data space for registration */
395 dev->name = chan->name;
396 dev->init = &if_init;
397 dev->priv = chan;
398 return 0;
401 /* Delete logical channel. */
402 static int del_if (wan_device_t *wandev, struct device *dev)
404 if (!dev) {
405 printk(KERN_ERR "cycx_x25:del_if:dev == NULL!\n");
406 return 0;
409 if (dev->priv) {
410 x25_channel_t *chan = dev->priv;
411 if (chan->svc) {
412 if (chan->local_addr)
413 kfree(chan->local_addr);
415 if (chan->state == WAN_CONNECTED)
416 del_timer(&chan->timer);
418 kfree(chan);
419 dev->priv = NULL;
422 return 0;
425 /* Network Device Interface */
426 /* Initialize Linux network interface.
428 * This routine is called only once for each interface, during Linux network
429 * interface registration. Returning anything but zero will fail interface
430 * registration. */
431 static int if_init (struct device *dev)
433 x25_channel_t *chan = dev->priv;
434 cycx_t *card = chan->card;
435 wan_device_t *wandev = &card->wandev;
437 /* Initialize device driver entry points */
438 dev->open = &if_open;
439 dev->stop = &if_close;
440 dev->hard_header = &if_header;
441 dev->rebuild_header = &if_rebuild_hdr;
442 dev->hard_start_xmit = &if_send;
443 dev->get_stats = &if_stats;
445 /* Initialize media-specific parameters */
446 dev->mtu = X25_CHAN_MTU;
447 dev->type = ARPHRD_X25; /* ARP h/w type */
448 dev->hard_header_len = 0; /* media header length */
449 dev->addr_len = 0; /* hardware address length */
451 if (!chan->svc)
452 *(u16*)dev->dev_addr = htons(chan->lcn);
454 /* Initialize hardware parameters (just for reference) */
455 dev->irq = wandev->irq;
456 dev->dma = wandev->dma;
457 dev->base_addr = wandev->ioport;
458 dev->mem_start = (unsigned long)wandev->maddr;
459 dev->mem_end = (unsigned long)(wandev->maddr + wandev->msize - 1);
460 dev->flags |= IFF_NOARP;
462 /* Set transmit buffer queue length */
463 dev->tx_queue_len = 10;
465 /* Initialize socket buffers */
466 dev_init_buffers(dev);
467 set_chan_state(dev, WAN_DISCONNECTED, OUT_INTR);
468 return 0;
471 /* Open network interface.
472 * o prevent module from unloading by incrementing use count
473 * o if link is disconnected then initiate connection
475 * Return 0 if O.k. or errno. */
476 static int if_open (struct device *dev)
478 x25_channel_t *chan = dev->priv;
479 cycx_t *card = chan->card;
481 if (dev->start)
482 return -EBUSY; /* only one open is allowed */
484 if (test_and_set_bit(0, (void*)&card->wandev.critical))
485 return -EAGAIN;
487 dev->interrupt = 0;
488 dev->tbusy = 0;
489 dev->start = 1;
490 cyclomx_open(card);
492 card->wandev.critical = 0;
493 return 0;
496 /* Close network interface.
497 * o reset flags.
498 * o if there's no more open channels then disconnect physical link. */
499 static int if_close (struct device *dev)
501 x25_channel_t *chan = dev->priv;
502 cycx_t *card = chan->card;
504 if (test_and_set_bit(0, (void*)&card->wandev.critical))
505 return -EAGAIN;
507 dev->start = 0;
509 if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
510 chan_disc(dev);
512 cyclomx_close(card);
514 card->wandev.critical = 0;
515 return 0;
518 /* Build media header.
519 * o encapsulate packet according to encapsulation type.
521 * The trick here is to put packet type (Ethertype) into 'protocol' field of
522 * the socket buffer, so that we don't forget it. If encapsulation fails,
523 * set skb->protocol to 0 and discard packet later.
525 * Return: media header length. */
526 static int if_header (struct sk_buff *skb, struct device *dev,
527 u16 type, void *daddr, void *saddr, unsigned len)
529 skb->protocol = type;
530 return dev->hard_header_len;
533 /* * Re-build media header.
534 * Return: 1 physical address resolved.
535 * 0 physical address not resolved */
536 static int if_rebuild_hdr (struct sk_buff *skb)
538 return 1;
541 /* Send a packet on a network interface.
542 * o set tbusy flag (marks start of the transmission).
543 * o check link state. If link is not up, then drop the packet.
544 * o check channel status. If it's down then initiate a call.
545 * o pass a packet to corresponding WAN device.
546 * o free socket buffer
548 * Return: 0 complete (socket buffer must be freed)
549 * non-0 packet may be re-transmitted (tbusy must be set)
551 * Notes:
552 * 1. This routine is called either by the protocol stack or by the "net
553 * bottom half" (with interrupts enabled).
554 * 2. Setting tbusy flag will inhibit further transmit requests from the
555 * protocol stack and can be used for flow control with protocol layer. */
556 static int if_send (struct sk_buff *skb, struct device *dev)
558 x25_channel_t *chan = dev->priv;
559 cycx_t *card = chan->card;
561 if (dev->tbusy) {
562 ++chan->ifstats.rx_dropped;
563 return -EBUSY;
566 dev->tbusy = 1;
568 reset_timer(dev);
570 if (!chan->svc)
571 chan->protocol = skb->protocol;
573 if (card->wandev.state != WAN_CONNECTED)
574 ++chan->ifstats.tx_dropped;
575 else if (chan->svc && chan->protocol &&
576 chan->protocol != skb->protocol) {
577 printk(KERN_INFO
578 "%s: unsupported Ethertype 0x%04X on interface %s!\n",
579 card->devname, skb->protocol, dev->name);
580 ++chan->ifstats.tx_errors;
581 } else switch (chan->state) {
582 case WAN_DISCONNECTED:
583 if (chan_connect(dev))
584 return -EBUSY;
585 /* fall thru */
586 case WAN_CONNECTED:
587 dev->trans_start = jiffies;
588 if (chan_send(dev, skb)) {
589 dev->tbusy = 1;
590 return -EBUSY;
592 break;
593 default:
594 ++chan->ifstats.tx_dropped;
595 ++card->wandev.stats.tx_dropped;
598 dev_kfree_skb(skb);
599 return 0;
602 /* Get Ethernet-style interface statistics.
603 * Return a pointer to struct net_device_stats */
604 static struct net_device_stats *if_stats (struct device *dev)
606 x25_channel_t *chan = dev->priv;
608 return chan ? &chan->ifstats : NULL;
611 /* Interrupt Handlers */
612 /* X.25 Interrupt Service Routine. */
613 static void cyx_isr (cycx_t *card)
615 unsigned long host_cpu_flags;
616 TX25Cmd cmd;
617 u16 z = 0;
619 card->in_isr = 1;
620 card->buff_int_mode_unbusy = 0;
622 if (test_and_set_bit(0, (void*)&card->wandev.critical)) {
623 printk(KERN_INFO "cyx_isr: %s, wandev.critical set to 0x%02X\n",
624 card->devname, card->wandev.critical);
625 card->in_isr = 0;
626 return;
629 /* For all interrupts set the critical flag to CRITICAL_RX_INTR.
630 * If the if_send routine is called with this flag set it will set
631 * the enable transmit flag to 1. (for a delayed interrupt) */
632 card->wandev.critical = CRITICAL_IN_ISR;
633 cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
634 switch (cmd.command) {
635 case X25_DATA_INDICATION:
636 rx_intr(card, &cmd);
637 break;
638 case X25_ACK_FROM_VC:
639 tx_intr(card, &cmd);
640 break;
641 case X25_LOG:
642 log_intr(card, &cmd);
643 break;
644 case X25_STATISTIC:
645 stat_intr(card, &cmd);
646 break;
647 case X25_CONNECT_CONFIRM:
648 connect_confirm_intr(card, &cmd);
649 break;
650 case X25_CONNECT_INDICATION:
651 connect_intr(card, &cmd);
652 break;
653 case X25_DISCONNECT_INDICATION:
654 disconnect_intr(card, &cmd);
655 break;
656 case X25_DISCONNECT_CONFIRM:
657 disconnect_confirm_intr(card, &cmd);
658 break;
659 case X25_LINE_ON:
660 cyclomx_set_state(card, WAN_CONNECTED);
661 break;
662 case X25_LINE_OFF:
663 cyclomx_set_state(card, WAN_DISCONNECTED);
664 break;
665 default:
666 spur_intr(card, &cmd); /* unwanted interrupt */
669 cycx_poke(&card->hw, 0, &z, sizeof(z));
670 cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
672 card->wandev.critical = CRITICAL_INTR_HANDLED;
674 if (card->wandev.enable_tx_int)
675 card->wandev.enable_tx_int = 0;
677 spin_lock_irqsave(&card->lock, host_cpu_flags);
678 card->in_isr = 0;
679 card->wandev.critical = 0;
680 spin_unlock_irqrestore(&card->lock, host_cpu_flags);
682 if (card->buff_int_mode_unbusy)
683 mark_bh(NET_BH);
686 /* Transmit interrupt handler.
687 * o Release socket buffer
688 * o Clear 'tbusy' flag */
689 static void tx_intr (cycx_t *card, TX25Cmd *cmd)
691 struct device *dev;
692 wan_device_t *wandev = &card->wandev;
693 u8 lcn;
695 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
697 /* unbusy device and then dev_tint(); */
698 if ((dev = get_dev_by_lcn (wandev, lcn)) != NULL) {
699 card->buff_int_mode_unbusy = 1;
700 dev->tbusy = 0;
701 } else
702 printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n",
703 card->devname, lcn);
706 /* Receive interrupt handler.
707 * This routine handles fragmented IP packets using M-bit according to the
708 * RFC1356.
709 * o map ligical channel number to network interface.
710 * o allocate socket buffer or append received packet to the existing one.
711 * o if M-bit is reset (i.e. it's the last packet in a sequence) then
712 * decapsulate packet and pass socket buffer to the protocol stack.
714 * Notes:
715 * 1. When allocating a socket buffer, if M-bit is set then more data is
716 * comming and we have to allocate buffer for the maximum IP packet size
717 * expected on this channel.
718 * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
719 * socket buffers available) the whole packet sequence must be discarded. */
720 static void rx_intr (cycx_t *card, TX25Cmd *cmd)
722 wan_device_t *wandev = &card->wandev;
723 struct device *dev;
724 x25_channel_t *chan;
725 struct sk_buff *skb;
726 u8 bitm, lcn;
727 int pktlen = cmd->len - 5;
729 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
730 cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
731 bitm &= 0x10;
733 if ((dev = get_dev_by_lcn(wandev, lcn)) == NULL) {
734 /* Invalid channel, discard packet */
735 printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
736 card->devname, lcn);
737 return;
740 chan = dev->priv;
741 reset_timer(dev);
743 if (chan->drop_sequence)
744 if (!bitm)
745 chan->drop_sequence = 0;
746 else
747 return;
749 if ((skb = chan->rx_skb) == NULL) {
750 /* Allocate new socket buffer */
751 int bufsize = bitm ? dev->mtu : pktlen;
753 if ((skb = dev_alloc_skb(bufsize +
754 dev->hard_header_len)) == NULL) {
755 printk(KERN_INFO "%s: no socket buffers available!\n",
756 card->devname);
757 chan->drop_sequence = 1;
758 ++chan->ifstats.rx_dropped;
759 return;
762 skb->dev = dev;
763 skb->protocol = htons(chan->protocol);
764 chan->rx_skb = skb;
767 if (skb_tailroom(skb) < pktlen) {
768 /* No room for the packet. Call off the whole thing! */
769 dev_kfree_skb(skb);
770 chan->rx_skb = NULL;
772 if (bitm)
773 chan->drop_sequence = 1;
775 printk(KERN_INFO "%s: unexpectedly long packet sequence "
776 "on interface %s!\n", card->devname, dev->name);
777 ++chan->ifstats.rx_length_errors;
778 return;
781 /* Append packet to the socket buffer */
782 cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
784 if (bitm)
785 return; /* more data is coming */
787 dev->last_rx = jiffies; /* timestamp */
788 chan->rx_skb = NULL; /* dequeue packet */
790 skb->protocol = htons(ETH_P_IP);
791 skb->dev = dev;
792 skb->mac.raw = skb->data;
793 netif_rx(skb);
794 ++chan->ifstats.rx_packets;
795 chan->ifstats.rx_bytes += skb->len;
798 /* Connect interrupt handler. */
799 static void connect_intr (cycx_t *card, TX25Cmd *cmd)
801 wan_device_t *wandev = &card->wandev;
802 struct device *dev = NULL;
803 x25_channel_t *chan;
804 u8 data[32],
805 local[24],
806 rem[24];
807 u8 lcn, sizelocal, sizerem;
809 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
810 cycx_peek(&card->hw, cmd->buf + 5, &sizelocal, sizeof(sizelocal));
811 cycx_peek(&card->hw, cmd->buf + 6, data, cmd->len - 6);
813 sizerem = sizelocal >> 4;
814 sizelocal &= 0x0F;
816 local[0] = rem[0] = '\0';
818 if (sizelocal)
819 nibble_to_byte(data, local, sizelocal, 0);
821 if (sizerem)
822 nibble_to_byte(data + (sizelocal >> 1), rem, sizerem, sizelocal & 1);
823 dprintk(KERN_INFO "connect_intr:lcn=%d, local=%s, remote=%s\n",
824 lcn, local, rem);
825 if ((dev = get_dev_by_dte_addr(wandev, rem)) == NULL) {
826 /* Invalid channel, discard packet */
827 printk(KERN_INFO "%s: connect not expected: remote %s!\n",
828 card->devname, rem);
829 return;
832 chan = dev->priv;
833 chan->lcn = lcn;
834 x25_connect_response(card, chan);
835 set_chan_state(dev, WAN_CONNECTED, IN_INTR);
838 /* Connect confirm interrupt handler. */
839 static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd)
841 wan_device_t *wandev = &card->wandev;
842 struct device *dev;
843 x25_channel_t *chan;
844 u8 lcn, key;
846 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
847 cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
848 dprintk(KERN_INFO "%s: connect_confirm_intr:lcn=%d, key=%d\n",
849 card->devname, lcn, key);
850 if ((dev = get_dev_by_lcn(wandev, -key)) == NULL) {
851 /* Invalid channel, discard packet */
852 clear_bit(--key, (void*)&card->u.x.connection_keys);
853 printk(KERN_INFO "%s: connect confirm not expected: lcn %d, "
854 "key=%d!\n", card->devname, lcn, key);
855 return;
858 clear_bit(--key, (void*)&card->u.x.connection_keys);
859 chan = dev->priv;
860 chan->lcn = lcn;
861 set_chan_state(dev, WAN_CONNECTED, IN_INTR);
864 /* Disonnect confirm interrupt handler. */
865 static void disconnect_confirm_intr (cycx_t *card, TX25Cmd *cmd)
867 wan_device_t *wandev = &card->wandev;
868 struct device *dev;
869 u8 lcn;
871 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
872 dprintk(KERN_INFO "%s: disconnect_confirm_intr:lcn=%d\n",
873 card->devname, lcn);
874 if ((dev = get_dev_by_lcn(wandev, lcn)) == NULL) {
875 /* Invalid channel, discard packet */
876 printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n",
877 card->devname, lcn);
878 return;
881 set_chan_state(dev, WAN_DISCONNECTED, IN_INTR);
884 /* disconnect interrupt handler. */
885 static void disconnect_intr (cycx_t *card, TX25Cmd *cmd)
887 wan_device_t *wandev = &card->wandev;
888 struct device *dev;
889 u8 lcn;
891 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
892 dprintk(KERN_INFO "disconnect_intr:lcn=%d\n", lcn);
893 x25_disconnect_response(card, 0, lcn);
895 if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL)
896 set_chan_state(dev, WAN_DISCONNECTED, IN_INTR);
899 /* LOG interrupt handler. */
900 static void log_intr (cycx_t *card, TX25Cmd *cmd)
902 #if CYCLOMX_X25_DEBUG
903 char bf[20];
904 u16 size, toread, link, msg_code;
905 u8 code, routine;
907 cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
908 cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
909 cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
910 /* at most 20 bytes are available... thanx to Daniela :) */
911 toread = size < 20 ? size : 20;
912 cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
913 cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
914 cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
916 printk(KERN_INFO "cyx_isr: X25_LOG (0x4500) indic.:\n");
917 printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf);
918 printk(KERN_INFO "Log message code=0x%X\n", msg_code);
919 printk(KERN_INFO "Link=%d\n", link);
920 printk(KERN_INFO "log code=0x%X\n", code);
921 printk(KERN_INFO "log routine=0x%X\n", routine);
922 printk(KERN_INFO "Message size=%d\n", size);
923 hex_dump("Message", bf, toread);
924 #endif
927 /* STATISTIC interrupt handler. */
928 static void stat_intr (cycx_t *card, TX25Cmd *cmd)
930 cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
931 sizeof(card->u.x.stats));
932 hex_dump("stat_intr", (unsigned char*)&card->u.x.stats,
933 sizeof(card->u.x.stats));
934 x25_dump_stats(&card->u.x.stats);
935 wake_up_interruptible(&card->wait_stats);
938 /* Spurious interrupt handler.
939 * o print a warning
940 * If number of spurious interrupts exceeded some limit, then ??? */
941 static void spur_intr (cycx_t *card, TX25Cmd *cmd)
943 printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n",
944 card->devname, cmd->command);
946 #ifdef CYCLOMX_X25_DEBUG
947 static void hex_dump(char *msg, unsigned char *p, int len)
949 unsigned char hex[1024],
950 * phex = hex;
952 if (len >= (sizeof(hex) / 2))
953 len = (sizeof(hex) / 2) - 1;
955 while (len--) {
956 sprintf(phex, "%02x", *p++);
957 phex += 2;
960 printk(KERN_INFO "%s: %s\n", msg, hex);
962 #endif
963 /* CYCLOM X Firmware-Specific Functions
965 * Almost all X.25 commands can unexpetedly fail due to so called 'X.25
966 * asynchronous events' such as restart, interrupt, incoming call request,
967 * call clear request, etc. They can't be ignored and have to be dealt with
968 * immediately. To tackle with this problem we execute each interface command
969 * in a loop until good return code is received or maximum number of retries
970 * is reached. Each interface command returns non-zero return code, an
971 * asynchronous event/error handler x25_error() is called.
973 /* Exec x25 command. */
974 static int x25_exec (cycx_t *card, int command, int link,
975 void *data1, int len1, void *data2, int len2)
977 TX25Cmd c;
978 u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
979 int err = 0;
981 c.command = command;
982 c.link = link;
983 c.len = len1 + len2;
985 if (test_and_set_bit(0, (void*)&card->u.x.critical))
986 return -EAGAIN;
988 /* write command */
989 cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
991 /* write x25 data */
992 if (data1) {
993 cycx_poke(&card->hw, addr, data1, len1);
995 if (data2)
996 if (len2 > 254) {
997 u32 addr1 = 0xA00 + 0x400 * link;
999 cycx_poke(&card->hw, addr + len1, data2, 249);
1000 cycx_poke(&card->hw, addr1, ((u8*) data2) + 249,
1001 len2 - 249);
1002 } else
1003 cycx_poke(&card->hw, addr + len1, data2, len2);
1006 /* generate interruption, executing command */
1007 cycx_intr(&card->hw);
1009 /* wait till card->mbox == 0 */
1010 err = cycx_exec(card->mbox);
1011 card->u.x.critical = 0;
1013 return err;
1016 /* Configure adapter. */
1017 static int x25_configure (cycx_t *card, TX25Config *conf)
1019 struct {
1020 u16 nlinks;
1021 TX25Config conf[2];
1022 } x25_cmd_conf;
1024 memset (&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1025 x25_cmd_conf.nlinks = 2;
1026 x25_cmd_conf.conf[0] = *conf;
1027 /* FIXME: we need to find a way in the wanrouter framework
1028 to configure the second link, for now lets use it
1029 with the same config from the first link, fixing
1030 the interface type to RS232, the speed in 38400 and
1031 the clock to external */
1032 x25_cmd_conf.conf[1] = *conf;
1033 x25_cmd_conf.conf[1].link = 1;
1034 x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1035 x25_cmd_conf.conf[1].clock = 8;
1036 x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1038 x25_dump_config(&x25_cmd_conf.conf[0]);
1039 x25_dump_config(&x25_cmd_conf.conf[1]);
1041 return x25_exec(card, X25_CONFIG, 0,
1042 &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1045 /* Get protocol statistics. */
1046 static int x25_get_stats (cycx_t *card)
1048 /* the firmware expects 20 in the size field!!!
1049 thanx to Daniela */
1050 int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1052 if (err)
1053 return err;
1055 interruptible_sleep_on(&card->wait_stats);
1057 if (signal_pending(current))
1058 return -EINTR;
1060 card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1061 card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1062 card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1063 card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1064 card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1065 card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1066 card->wandev.stats.rx_dropped = 0; /* not available from fw */
1067 card->wandev.stats.rx_errors = 0; /* not available from fw */
1068 card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1069 card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1070 card->wandev.stats.tx_dropped = 0; /* not available from fw */
1071 card->wandev.stats.collisions = 0; /* not available from fw */
1072 card->wandev.stats.tx_errors = 0; /* not available from fw */
1074 x25_dump_devs(&card->wandev);
1075 return 0;
1078 /* return the number of nibbles */
1079 static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1081 int i = 0;
1083 if (*nibble && *s) {
1084 d[i] |= *s++ - '0';
1085 *nibble = 0;
1086 ++i;
1089 while (*s) {
1090 d[i] = (*s - '0') << 4;
1091 if (*(s + 1))
1092 d[i] |= *(s + 1) - '0';
1093 else {
1094 *nibble = 1;
1095 break;
1097 ++i;
1098 s += 2;
1101 return i;
1104 static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1106 if (nibble) {
1107 *d++ = '0' + (*s++ & 0x0F);
1108 --len;
1111 while (len) {
1112 *d++ = '0' + (*s >> 4);
1113 if (--len) {
1114 *d++ = '0' + (*s & 0x0F);
1115 --len;
1116 } else break;
1118 ++s;
1121 *d = '\0';
1124 /* Place X.25 call. */
1125 static int x25_place_call (cycx_t *card, x25_channel_t *chan)
1127 int err = 0,
1128 retry = MAX_CMD_RETRY,
1129 len;
1130 char data[64],
1131 nibble = 0,
1132 mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1133 remotelen = strlen(chan->addr);
1134 u8 key;
1136 if (card->u.x.connection_keys == ~0UL) {
1137 printk(KERN_INFO "%s: too many simultaneous connection "
1138 "requests!\n", card->devname);
1139 return -EAGAIN;
1142 key = ffz(card->u.x.connection_keys);
1143 set_bit(key, (void*)&card->u.x.connection_keys);
1144 ++key;
1145 dprintk(KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1146 memset(data, 0, sizeof(data));
1147 data[1] = key; /* user key */
1148 data[2] = 0x10;
1149 data[4] = 0x0B;
1151 len = byte_to_nibble(chan->addr, data + 6, &nibble);
1152 len += chan->local_addr ? byte_to_nibble(chan->local_addr,
1153 data + 6 + len, &nibble) : 0;
1154 if (nibble)
1155 ++len;
1156 data[5] = mylen << 4 | remotelen;
1157 data[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanx to Daniela :) */
1159 do err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1160 &data, 7 + len + 1, NULL, 0);
1161 while (err && retry--);
1163 if (err)
1164 clear_bit(--key, (void*)&card->u.x.connection_keys);
1165 else {
1166 chan->lcn = -key;
1167 chan->protocol = ETH_P_IP;
1170 return err;
1173 /* Place X.25 CONNECT RESPONSE. */
1174 static int x25_connect_response (cycx_t *card, x25_channel_t *chan)
1176 int err = 0,
1177 retry = MAX_CMD_RETRY;
1178 char data[32];
1180 memset(data, 0, sizeof(data));
1181 data[0] = data[3] = chan->lcn;
1182 data[2] = 0x10;
1183 data[4] = 0x0F;
1184 data[7] = 0xCC; /* TCP/IP over X.25, thanx Daniela */
1186 do err = x25_exec(card, X25_CONNECT_RESPONSE, chan->link,
1187 &data, 8, NULL, 0);
1188 while (err && retry--);
1190 return err;
1193 /* Place X.25 DISCONNECT RESPONSE. */
1194 static int x25_disconnect_response (cycx_t *card, u8 link, u8 lcn)
1196 int err = 0,
1197 retry = MAX_CMD_RETRY;
1198 char data[5];
1200 memset(data, 0, sizeof(data));
1201 data[0] = data[3] = lcn;
1202 data[2] = 0x10;
1203 data[4] = 0x17;
1204 do err = x25_exec(card, X25_DISCONNECT_RESPONSE, link,
1205 &data, 5, NULL, 0);
1206 while (err && retry--);
1208 return err;
1211 /* Clear X.25 call. */
1212 static int x25_clear_call (cycx_t *card, u8 link, u8 lcn, u8 cause, u8 diagn)
1214 int retry = MAX_CMD_RETRY,
1215 err;
1216 u8 data[7];
1218 memset(data, 0, sizeof(data));
1219 data[0] = data[3] = lcn;
1220 data[2] = 0x10;
1221 data[4] = 0x13;
1222 data[5] = cause;
1223 data[6] = diagn;
1225 do err = x25_exec(card, X25_DISCONNECT_REQUEST, link, data, 7, NULL, 0);
1226 while (err && retry--);
1228 return err;
1231 /* Send X.25 data packet. */
1232 static int x25_send (cycx_t *card, u8 link, u8 lcn, u8 bitm, int len, void *buf)
1234 int err = 0,
1235 retry = MAX_CMD_RETRY;
1236 u8 data[] = "?\xFF\x10??";
1238 data[0] = data[3] = lcn;
1239 data[4] = bitm;
1241 do err = x25_exec(card, X25_DATA_REQUEST, link, &data, 5, buf, len);
1242 while (err && retry--);
1244 return err;
1247 /* Miscellaneous */
1248 /* Find network device by its channel number. */
1249 static struct device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn)
1251 struct device *dev = wandev->dev;
1253 for (; dev; dev = dev->slave)
1254 if (((x25_channel_t*)dev->priv)->lcn == lcn)
1255 break;
1256 return dev;
1259 /* Find network device by its remote dte address. */
1260 static struct device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte)
1262 struct device *dev = wandev->dev;
1264 for (; dev; dev = dev->slave)
1265 if (!strcmp (((x25_channel_t*)dev->priv)->addr, dte))
1266 break;
1267 return dev;
1270 /* Initiate connection on the logical channel.
1271 * o for PVC we just get channel configuration
1272 * o for SVCs place an X.25 call
1274 * Return: 0 connected
1275 * >0 connection in progress
1276 * <0 failure */
1277 static int chan_connect (struct device *dev)
1279 x25_channel_t *chan = dev->priv;
1280 cycx_t *card = chan->card;
1282 if (chan->svc) {
1283 if (!chan->addr[0])
1284 return -EINVAL; /* no destination address */
1285 dprintk(KERN_INFO "%s: placing X.25 call to %s...\n",
1286 card->devname, chan->addr);
1287 if (x25_place_call(card, chan))
1288 return -EIO;
1289 set_chan_state(dev, WAN_CONNECTING, OUT_INTR);
1290 return 1;
1291 } else
1292 set_chan_state(dev, WAN_CONNECTED, OUT_INTR);
1294 return 0;
1297 /* Disconnect logical channel.
1298 * o if SVC then clear X.25 call */
1299 static void chan_disc (struct device *dev)
1301 x25_channel_t *chan = dev->priv;
1303 if (chan->svc) {
1304 x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1305 set_chan_state(dev, WAN_DISCONNECTING, OUT_INTR);
1306 } else
1307 set_chan_state(dev, WAN_DISCONNECTED, OUT_INTR);
1310 /* Called by kernel timer */
1311 static void chan_timer (unsigned long data)
1313 struct device *dev = (struct device*) data;
1314 x25_channel_t *chan = dev->priv;
1316 switch (chan->state) {
1317 case WAN_CONNECTED:
1318 chan_disc(dev);
1319 break;
1320 default:
1321 printk (KERN_ERR "%s: chan_timer for svc (%s) not "
1322 "connected!\n",
1323 chan->card->devname, dev->name);
1327 /* Set logical channel state. */
1328 static void set_chan_state (struct device *dev, u8 state, u8 outside_intr)
1330 x25_channel_t *chan = dev->priv;
1331 cycx_t *card = chan->card;
1332 u32 flags = 0;
1334 if (outside_intr)
1335 spin_lock(&card->lock);
1336 else
1337 spin_lock_irqsave(&card->lock, flags);
1339 if (chan->state != state) {
1340 if (chan->svc && chan->state == WAN_CONNECTED)
1341 del_timer(&chan->timer);
1343 switch (state) {
1344 case WAN_CONNECTED:
1345 printk (KERN_INFO "%s: interface %s "
1346 "connected!\n",
1347 card->devname, dev->name);
1348 *(u16*)dev->dev_addr = htons(chan->lcn);
1349 dev->tbusy = 0;
1350 reset_timer(dev);
1351 break;
1353 case WAN_CONNECTING:
1354 printk (KERN_INFO "%s: interface %s "
1355 "connecting...\n",
1356 card->devname, dev->name);
1357 break;
1359 case WAN_DISCONNECTING:
1360 printk (KERN_INFO "%s: interface %s "
1361 "disconnecting...\n",
1362 card->devname, dev->name);
1363 break;
1365 case WAN_DISCONNECTED:
1366 printk (KERN_INFO "%s: interface %s "
1367 "disconnected!\n",
1368 card->devname, dev->name);
1369 if (chan->svc) {
1370 *(unsigned short*)dev->dev_addr = 0;
1371 chan->lcn = 0;
1373 break;
1376 chan->state = state;
1379 if (outside_intr)
1380 spin_unlock(&card->lock);
1381 else
1382 spin_unlock_irqrestore(&card->lock, flags);
1385 /* Send packet on a logical channel.
1386 * When this function is called, tx_skb field of the channel data space
1387 * points to the transmit socket buffer. When transmission is complete,
1388 * release socket buffer and reset 'tbusy' flag.
1390 * Return: 0 - transmission complete
1391 * 1 - busy
1393 * Notes:
1394 * 1. If packet length is greater than MTU for this channel, we'll fragment
1395 * the packet into 'complete sequence' using M-bit.
1396 * 2. When transmission is complete, an event notification should be issued
1397 * to the router. */
1398 static int chan_send (struct device *dev, struct sk_buff *skb)
1400 x25_channel_t *chan = dev->priv;
1401 cycx_t *card = chan->card;
1402 int bitm = 0; /* final packet */
1403 unsigned len = skb->len;
1405 if (skb->len > card->wandev.mtu) {
1406 len = card->wandev.mtu;
1407 bitm = 0x10; /* set M-bit (more data) */
1410 if (x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1411 return 1;
1413 if (bitm) {
1414 skb_pull(skb, len);
1415 return 1;
1418 ++chan->ifstats.tx_packets;
1419 chan->ifstats.tx_bytes += len;
1420 return 0;
1423 /* Convert line speed in bps to a number used by cyclom 2x code. */
1424 static u8 bps_to_speed_code (u32 bps)
1426 u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1428 if (bps >= 512000) number = 8;
1429 else if (bps >= 256000) number = 7;
1430 else if (bps >= 64000) number = 6;
1431 else if (bps >= 38400) number = 5;
1432 else if (bps >= 19200) number = 4;
1433 else if (bps >= 9600) number = 3;
1434 else if (bps >= 4800) number = 2;
1435 else if (bps >= 2400) number = 1;
1437 return number;
1440 /* log base 2 */
1441 static u8 log2 (u32 n)
1443 u8 log = 0;
1445 if (!n)
1446 return 0;
1448 while (n > 1) {
1449 n >>= 1;
1450 ++log;
1453 return log;
1456 /* Convert decimal string to unsigned integer.
1457 * If len != 0 then only 'len' characters of the string are converted. */
1458 static unsigned dec_to_uint (u8 *str, int len)
1460 unsigned val = 0;
1462 if (!len)
1463 len = strlen(str);
1465 for (; len && is_digit(*str); ++str, --len)
1466 val = (val * 10) + (*str - (unsigned)'0');
1468 return val;
1471 static void reset_timer(struct device *dev)
1473 x25_channel_t *chan = dev->priv;
1475 if (!chan->svc)
1476 return;
1478 del_timer(&chan->timer);
1479 chan->timer.expires = jiffies + chan->idle_tmout * HZ;
1480 add_timer(&chan->timer);
1482 #ifdef CYCLOMX_X25_DEBUG
1483 static void x25_dump_config(TX25Config *conf)
1485 printk (KERN_INFO "x25 configuration\n");
1486 printk (KERN_INFO "-----------------\n");
1487 printk (KERN_INFO "link number=%d\n", conf->link);
1488 printk (KERN_INFO "line speed=%d\n", conf->speed);
1489 printk (KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1490 printk (KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1491 printk (KERN_INFO "level 2 window=%d\n", conf->n2win);
1492 printk (KERN_INFO "level 3 window=%d\n", conf->n3win);
1493 printk (KERN_INFO "# logical channels=%d\n", conf->nvc);
1494 printk (KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1495 printk (KERN_INFO "my address=%d\n", conf->locaddr);
1496 printk (KERN_INFO "remote address=%d\n", conf->remaddr);
1497 printk (KERN_INFO "t1=%d seconds\n", conf->t1);
1498 printk (KERN_INFO "t2=%d seconds\n", conf->t2);
1499 printk (KERN_INFO "t21=%d seconds\n", conf->t21);
1500 printk (KERN_INFO "# PVCs=%d\n", conf->npvc);
1501 printk (KERN_INFO "t23=%d seconds\n", conf->t23);
1502 printk (KERN_INFO "flags=0x%x\n", conf->flags);
1505 static void x25_dump_stats(TX25Stats *stats)
1507 printk (KERN_INFO "x25 statistics\n");
1508 printk (KERN_INFO "--------------\n");
1509 printk (KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1510 printk (KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1511 printk (KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1512 printk (KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1513 printk (KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1514 printk (KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1515 printk (KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1516 printk (KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1517 printk (KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1518 printk (KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1521 static void x25_dump_devs(wan_device_t *wandev)
1523 struct device *dev = wandev->dev;
1525 printk (KERN_INFO "x25 dev states\n");
1526 printk (KERN_INFO "name: addr: tbusy:\n");
1527 printk (KERN_INFO "----------------------------\n");
1529 for (; dev; dev = dev->slave) {
1530 x25_channel_t *chan = dev->priv;
1532 printk (KERN_INFO "%-5.5s %-15.15s %ld\n",
1533 chan->name, chan->addr, dev->tbusy);
1537 #endif /* CYCLOMX_X25_DEBUG */
1538 /* End */