Import 2.3.47pre1
[davej-history.git] / drivers / net / wan / cycx_x25.c
blobe561257343a6b35c902413b9beed0fb48912a778
1 /*
2 * cycx_x25.c Cyclom 2X WAN Link Driver. X.25 module.
4 * Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 * Copyright: (c) 1998-2000 Arnaldo Carvalho de Melo
8 * Based on sdla_x25.c by Gene Kozin <genek@compuserve.com>
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 * 2000/01/08 acme cleanup
16 * 1999/10/27 acme use ARPHRD_HWX25 so that the X.25 stack know
17 * that we have a X.25 stack implemented in
18 * firmware onboard
19 * 1999/10/18 acme support for X.25 sockets in if_send,
20 * beware: socket(AF_X25...) IS WORK IN PROGRESS,
21 * TCP/IP over X.25 via wanrouter not affected,
22 * working.
23 * 1999/10/09 acme chan_disc renamed to chan_disconnect,
24 * began adding support for X.25 sockets:
25 * conf->protocol in new_if
26 * 1999/10/05 acme fixed return E... to return -E...
27 * 1999/08/10 acme serialized access to the card thru a spinlock
28 * in x25_exec
29 * 1999/08/09 acme removed per channel spinlocks
30 * removed references to enable_tx_int
31 * 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated
32 * if_send simplified
33 * 1999/05/25 acme fixed t1, t2, t21 & t23 configuration
34 * use spinlocks instead of cli/sti in some points
35 * 1999/05/24 acme finished the x25_get_stat function
36 * 1999/05/23 acme dev->type = ARPHRD_X25 (tcpdump only works,
37 * AFAIT, with ARPHRD_ETHER). This seems to be
38 * needed to use socket(AF_X25)...
39 * Now the config file must specify a peer media
40 * address for svc channels over a crossover cable.
41 * Removed hold_timeout from x25_channel_t,
42 * not used.
43 * A little enhancement in the DEBUG processing
44 * 1999/05/22 acme go to DISCONNECTED in disconnect_confirm_intr,
45 * instead of chan_disc.
46 * 1999/05/16 marcelo fixed timer initialization in SVCs
47 * 1999/01/05 acme x25_configure now get (most of) all
48 * parameters...
49 * 1999/01/05 acme pktlen now (correctly) uses log2 (value
50 * configured)
51 * 1999/01/03 acme judicious use of data types (u8, u16, u32, etc)
52 * 1999/01/03 acme cyx_isr: reset dpmbase to acknowledge
53 * indication (interrupt from cyclom 2x)
54 * 1999/01/02 acme cyx_isr: first hackings...
55 * 1999/01/0203 acme when initializing an array don't give less
56 * elements than declared...
57 * example: char send_cmd[6] = "?\xFF\x10";
58 * you'll gonna lose a couple hours, 'cause your
59 * brain won't admit that there's an error in the
60 * above declaration... the side effect is that
61 * memset is put into the unresolved symbols
62 * instead of using the inline memset functions...
63 * 1999/01/02 acme began chan_connect, chan_send, x25_send
64 * 1998/12/31 acme x25_configure
65 * this code can be compiled as non module
66 * 1998/12/27 acme code cleanup
67 * IPX code wiped out! let's decrease code
68 * complexity for now, remember: I'm learning! :)
69 * bps_to_speed_code OK
70 * 1998/12/26 acme Minimal debug code cleanup
71 * 1998/08/08 acme Initial version.
74 #define CYCLOMX_X25_DEBUG 1
76 #include <linux/version.h>
77 #include <linux/kernel.h> /* printk(), and other useful stuff */
78 #include <linux/stddef.h> /* offsetof(), etc. */
79 #include <linux/errno.h> /* return codes */
80 #include <linux/string.h> /* inline memset(), etc. */
81 #include <linux/malloc.h> /* kmalloc(), kfree() */
82 #include <linux/wanrouter.h> /* WAN router definitions */
83 #include <asm/byteorder.h> /* htons(), etc. */
84 #include <linux/if_arp.h> /* ARPHRD_HWX25 */
85 #include <linux/cyclomx.h> /* Cyclom 2X common user API definitions */
86 #include <linux/cycx_x25.h> /* X.25 firmware API definitions */
88 /* Defines & Macros */
89 #define MAX_CMD_RETRY 5
90 #define X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
92 /* Data Structures */
93 /* This is an extension of the 'struct net_device' we create for each network
94 interface to keep the rest of X.25 channel-specific data. */
95 typedef struct x25_channel {
96 /* This member must be first. */
97 struct net_device *slave; /* WAN slave */
99 char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
100 char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
101 char *local_addr; /* local media address, ASCIIZ -
102 svc thru crossover cable */
103 s16 lcn; /* logical channel number/conn.req.key*/
104 u8 link;
105 struct timer_list timer; /* timer used for svc channel disc. */
106 u16 protocol; /* ethertype, 0 - multiplexed */
107 u8 svc; /* 0 - permanent, 1 - switched */
108 u8 state; /* channel state */
109 u8 drop_sequence; /* mark sequence for dropping */
110 u32 idle_tmout; /* sec, before disconnecting */
111 struct sk_buff *rx_skb; /* receive socket buffer */
112 cycx_t *card; /* -> owner */
113 struct enet_statistics ifstats; /* interface statistics */
114 } x25_channel_t;
116 /* Function Prototypes */
117 /* WAN link driver entry points. These are called by the WAN router module. */
118 static int update (wan_device_t *wandev),
119 new_if (wan_device_t *wandev, struct net_device *dev,
120 wanif_conf_t *conf),
121 del_if (wan_device_t *wandev, struct net_device *dev);
123 /* Network device interface */
124 static int if_init (struct net_device *dev),
125 if_open (struct net_device *dev),
126 if_close (struct net_device *dev),
127 if_header (struct sk_buff *skb, struct net_device *dev,
128 u16 type, void *daddr, void *saddr, unsigned len),
129 if_rebuild_hdr (struct sk_buff *skb),
130 if_send (struct sk_buff *skb, struct net_device *dev);
132 static struct net_device_stats * if_stats (struct net_device *dev);
134 /* Interrupt handlers */
135 static void cyx_isr (cycx_t *card),
136 tx_intr (cycx_t *card, TX25Cmd *cmd),
137 rx_intr (cycx_t *card, TX25Cmd *cmd),
138 log_intr (cycx_t *card, TX25Cmd *cmd),
139 stat_intr (cycx_t *card, TX25Cmd *cmd),
140 connect_confirm_intr (cycx_t *card, TX25Cmd *cmd),
141 disconnect_confirm_intr (cycx_t *card, TX25Cmd *cmd),
142 connect_intr (cycx_t *card, TX25Cmd *cmd),
143 disconnect_intr (cycx_t *card, TX25Cmd *cmd),
144 spur_intr (cycx_t *card, TX25Cmd *cmd);
146 /* X.25 firmware interface functions */
147 static int x25_configure (cycx_t *card, TX25Config *conf),
148 x25_get_stats (cycx_t *card),
149 x25_send (cycx_t *card, u8 link, u8 lcn, u8 bitm, int len,
150 void *buf),
151 x25_connect_response (cycx_t *card, x25_channel_t *chan),
152 x25_disconnect_response (cycx_t *card, u8 link, u8 lcn);
154 /* channel functions */
155 static int chan_connect (struct net_device *dev),
156 chan_send (struct net_device *dev, struct sk_buff *skb);
158 static void chan_disconnect (struct net_device *dev),
159 chan_x25_send_event(struct net_device *dev, u8 event);
161 /* Miscellaneous functions */
162 static void set_chan_state (struct net_device *dev, u8 state),
163 chan_timer (unsigned long d);
165 static void nibble_to_byte (u8 *s, u8 *d, u8 len, u8 nibble),
166 reset_timer (struct net_device *dev);
168 static u8 bps_to_speed_code (u32 bps);
169 static u8 log2 (u32 n);
171 static unsigned dec_to_uint (u8 *str, int len);
173 static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn);
174 static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte);
176 #ifdef CYCLOMX_X25_DEBUG
177 static void hex_dump(char *msg, unsigned char *p, int len);
178 static void x25_dump_config(TX25Config *conf);
179 static void x25_dump_stats(TX25Stats *stats);
180 static void x25_dump_devs(wan_device_t *wandev);
181 #define dprintk(format, a...) printk(format, ##a)
182 #else
183 #define hex_dump(msg, p, len)
184 #define x25_dump_config(conf)
185 #define x25_dump_stats(stats)
186 #define x25_dump_devs(wandev)
187 #define dprintk(format, a...)
188 #endif
189 /* Public Functions */
191 /* X.25 Protocol Initialization routine.
193 * This routine is called by the main Cyclom 2X module during setup. At this
194 * point adapter is completely initialized and X.25 firmware is running.
195 * o configure adapter
196 * o initialize protocol-specific fields of the adapter data space.
198 * Return: 0 o.k.
199 * < 0 failure. */
200 int cyx_init (cycx_t *card, wandev_conf_t *conf)
202 TX25Config cfg;
204 /* Verify configuration ID */
205 if (conf->config_id != WANCONFIG_X25) {
206 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
207 card->devname, conf->config_id);
208 return -EINVAL;
211 /* Initialize protocol-specific fields */
212 card->mbox = card->hw.dpmbase + X25_MBOX_OFFS;
213 card->u.x.connection_keys = 0;
214 card->u.x.lock = SPIN_LOCK_UNLOCKED;
216 /* Configure adapter. Here we set reasonable defaults, then parse
217 * device configuration structure and set configuration options.
218 * Most configuration options are verified and corrected (if
219 * necessary) since we can't rely on the adapter to do so and don't
220 * want it to fail either. */
221 memset(&cfg, 0, sizeof(cfg));
222 cfg.link = 0;
223 cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
224 cfg.speed = bps_to_speed_code(conf->bps);
225 cfg.n3win = 7;
226 cfg.n2win = 2;
227 cfg.n2 = 5;
228 cfg.nvc = 1;
229 cfg.npvc = 1;
230 cfg.flags = 0x02; /* default = V35 */
231 cfg.t1 = 10; /* line carrier timeout */
232 cfg.t2 = 29; /* tx timeout */
233 cfg.t21 = 180; /* CALL timeout */
234 cfg.t23 = 180; /* CLEAR timeout */
236 /* adjust MTU */
237 if (!conf->mtu || conf->mtu >= 512)
238 card->wandev.mtu = 512;
239 else if (conf->mtu >= 256)
240 card->wandev.mtu = 256;
241 else if (conf->mtu >= 128)
242 card->wandev.mtu = 128;
243 else
244 card->wandev.mtu = 64;
246 cfg.pktlen = log2(card->wandev.mtu);
248 if (conf->station == WANOPT_DTE) {
249 cfg.locaddr = 3; /* DTE */
250 cfg.remaddr = 1; /* DCE */
251 } else {
252 cfg.locaddr = 1; /* DCE */
253 cfg.remaddr = 3; /* DTE */
256 if (conf->interface == WANOPT_RS232)
257 cfg.flags = 0; /* FIXME just reset the 2nd bit */
259 if (conf->u.x25.hi_pvc) {
260 card->u.x.hi_pvc = min(conf->u.x25.hi_pvc, 4095);
261 card->u.x.lo_pvc = min(conf->u.x25.lo_pvc, card->u.x.hi_pvc);
264 if (conf->u.x25.hi_svc) {
265 card->u.x.hi_svc = min(conf->u.x25.hi_svc, 4095);
266 card->u.x.lo_svc = min(conf->u.x25.lo_svc, card->u.x.hi_svc);
269 if (card->u.x.lo_pvc == 255)
270 cfg.npvc = 0;
271 else
272 cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
274 cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
276 if (conf->u.x25.hdlc_window)
277 cfg.n2win = min(conf->u.x25.hdlc_window, 7);
279 if (conf->u.x25.pkt_window)
280 cfg.n3win = min(conf->u.x25.pkt_window, 7);
282 if (conf->u.x25.t1)
283 cfg.t1 = min(conf->u.x25.t1, 30);
285 if (conf->u.x25.t2)
286 cfg.t2 = min(conf->u.x25.t2, 30);
288 if (conf->u.x25.t11_t21)
289 cfg.t21 = min(conf->u.x25.t11_t21, 30);
291 if (conf->u.x25.t13_t23)
292 cfg.t23 = min(conf->u.x25.t13_t23, 30);
294 if (conf->u.x25.n2)
295 cfg.n2 = min(conf->u.x25.n2, 30);
297 /* initialize adapter */
298 if (x25_configure(card, &cfg))
299 return -EIO;
301 /* Initialize protocol-specific fields of adapter data space */
302 card->wandev.bps = conf->bps;
303 card->wandev.interface = conf->interface;
304 card->wandev.clocking = conf->clocking;
305 card->wandev.station = conf->station;
306 card->isr = cyx_isr;
307 card->exec = NULL;
308 card->wandev.update = update;
309 card->wandev.new_if = new_if;
310 card->wandev.del_if = del_if;
311 card->wandev.state = WAN_DISCONNECTED;
313 return 0;
316 /* WAN Device Driver Entry Points */
317 /* Update device status & statistics. */
318 static int update (wan_device_t *wandev)
320 /* sanity checks */
321 if (!wandev || !wandev->private)
322 return -EFAULT;
324 if (wandev->state == WAN_UNCONFIGURED)
325 return -ENODEV;
327 x25_get_stats(wandev->private);
329 return 0;
332 /* Create new logical channel.
333 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
334 * handled.
335 * o parse media- and hardware-specific configuration
336 * o make sure that a new channel can be created
337 * o allocate resources, if necessary
338 * o prepare network device structure for registration.
340 * Return: 0 o.k.
341 * < 0 failure (channel will not be created) */
342 static int new_if (wan_device_t *wandev, struct net_device *dev,
343 wanif_conf_t *conf)
345 cycx_t *card = wandev->private;
346 x25_channel_t *chan;
347 int err = 0;
349 if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
350 printk(KERN_INFO "%s: invalid interface name!\n",card->devname);
351 return -EINVAL;
354 /* allocate and initialize private data */
355 if ((chan = kmalloc(sizeof(x25_channel_t), GFP_KERNEL)) == NULL)
356 return -ENOMEM;
358 memset(chan, 0, sizeof(x25_channel_t));
359 strcpy(chan->name, conf->name);
360 chan->card = card;
361 chan->link = conf->port;
362 chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
363 chan->rx_skb = NULL;
364 /* only used in svc connected thru crossover cable */
365 chan->local_addr = NULL;
367 if (conf->addr[0] == '@') { /* SVC */
368 int len = strlen(conf->local_addr);
370 if (len) {
371 if (len > WAN_ADDRESS_SZ) {
372 printk(KERN_ERR "%s: %s local addr too long!\n",
373 wandev->name, chan->name);
374 kfree(chan);
375 return -EINVAL;
376 } else {
377 chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
379 if (!chan->local_addr) {
380 kfree(chan);
381 return -ENOMEM;
385 strncpy(chan->local_addr, conf->local_addr,
386 WAN_ADDRESS_SZ);
389 chan->svc = 1;
390 strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
391 init_timer(&chan->timer);
392 chan->timer.function = chan_timer;
393 chan->timer.data = (unsigned long)dev;
395 /* Set channel timeouts (default if not specified) */
396 chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
397 } else if (is_digit(conf->addr[0])) { /* PVC */
398 s16 lcn = dec_to_uint(conf->addr, 0);
400 if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
401 chan->lcn = lcn;
402 else {
403 printk(KERN_ERR
404 "%s: PVC %u is out of range on interface %s!\n",
405 wandev->name, lcn, chan->name);
406 err = -EINVAL;
408 } else {
409 printk(KERN_ERR "%s: invalid media address on interface %s!\n",
410 wandev->name, chan->name);
411 err = -EINVAL;
414 if (err) {
415 if (chan->local_addr)
416 kfree(chan->local_addr);
418 kfree(chan);
419 return err;
422 /* prepare network device data space for registration */
423 dev->name = chan->name;
424 dev->init = if_init;
425 dev->priv = chan;
427 return 0;
430 /* Delete logical channel. */
431 static int del_if (wan_device_t *wandev, struct net_device *dev)
433 if (dev->priv) {
434 x25_channel_t *chan = dev->priv;
436 if (chan->svc) {
437 if (chan->local_addr)
438 kfree(chan->local_addr);
440 if (chan->state == WAN_CONNECTED)
441 del_timer(&chan->timer);
444 kfree(chan);
445 dev->priv = NULL;
448 return 0;
451 /* Network Device Interface */
452 /* Initialize Linux network interface.
454 * This routine is called only once for each interface, during Linux network
455 * interface registration. Returning anything but zero will fail interface
456 * registration. */
457 static int if_init (struct net_device *dev)
459 x25_channel_t *chan = dev->priv;
460 cycx_t *card = chan->card;
461 wan_device_t *wandev = &card->wandev;
463 /* Initialize device driver entry points */
464 dev->open = if_open;
465 dev->stop = if_close;
466 dev->hard_header = if_header;
467 dev->rebuild_header = if_rebuild_hdr;
468 dev->hard_start_xmit = if_send;
469 dev->get_stats = if_stats;
471 /* Initialize media-specific parameters */
472 dev->mtu = X25_CHAN_MTU;
473 dev->type = ARPHRD_HWX25; /* ARP h/w type */
474 dev->hard_header_len = 0; /* media header length */
475 dev->addr_len = 0; /* hardware address length */
477 if (!chan->svc)
478 *(u16*)dev->dev_addr = htons(chan->lcn);
480 /* Initialize hardware parameters (just for reference) */
481 dev->irq = wandev->irq;
482 dev->dma = wandev->dma;
483 dev->base_addr = wandev->ioport;
484 dev->mem_start = (unsigned long)wandev->maddr;
485 dev->mem_end = (unsigned long)(wandev->maddr + wandev->msize - 1);
486 dev->flags |= IFF_NOARP;
488 /* Set transmit buffer queue length */
489 dev->tx_queue_len = 10;
491 /* Initialize socket buffers */
492 dev_init_buffers(dev);
493 set_chan_state(dev, WAN_DISCONNECTED);
495 return 0;
498 /* Open network interface.
499 * o prevent module from unloading by incrementing use count
500 * o if link is disconnected then initiate connection
502 * Return 0 if O.k. or errno. */
503 static int if_open (struct net_device *dev)
505 x25_channel_t *chan = dev->priv;
506 cycx_t *card = chan->card;
508 if (netif_running(dev))
509 return -EBUSY; /* only one open is allowed */
511 netif_start_queue(dev);
512 cyclomx_mod_inc_use_count(card);
514 return 0;
517 /* Close network interface.
518 * o reset flags.
519 * o if there's no more open channels then disconnect physical link. */
520 static int if_close (struct net_device *dev)
522 x25_channel_t *chan = dev->priv;
523 cycx_t *card = chan->card;
525 netif_stop_queue(dev);
527 if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
528 chan_disconnect(dev);
530 cyclomx_mod_dec_use_count(card);
532 return 0;
535 /* Build media header.
536 * o encapsulate packet according to encapsulation type.
538 * The trick here is to put packet type (Ethertype) into 'protocol' field of
539 * the socket buffer, so that we don't forget it. If encapsulation fails,
540 * set skb->protocol to 0 and discard packet later.
542 * Return: media header length. */
543 static int if_header (struct sk_buff *skb, struct net_device *dev,
544 u16 type, void *daddr, void *saddr, unsigned len)
546 skb->protocol = type;
548 return dev->hard_header_len;
551 /* * Re-build media header.
552 * Return: 1 physical address resolved.
553 * 0 physical address not resolved */
554 static int if_rebuild_hdr (struct sk_buff *skb)
556 return 1;
559 /* Send a packet on a network interface.
560 * o set busy flag (marks start of the transmission).
561 * o check link state. If link is not up, then drop the packet.
562 * o check channel status. If it's down then initiate a call.
563 * o pass a packet to corresponding WAN device.
564 * o free socket buffer
566 * Return: 0 complete (socket buffer must be freed)
567 * non-0 packet may be re-transmitted (tbusy must be set)
569 * Notes:
570 * 1. This routine is called either by the protocol stack or by the "net
571 * bottom half" (with interrupts enabled).
572 * 2. Setting tbusy flag will inhibit further transmit requests from the
573 * protocol stack and can be used for flow control with protocol layer. */
574 static int if_send (struct sk_buff *skb, struct net_device *dev)
576 x25_channel_t *chan = dev->priv;
577 cycx_t *card = chan->card;
579 if (!chan->svc)
580 chan->protocol = skb->protocol;
582 if (card->wandev.state != WAN_CONNECTED)
583 ++chan->ifstats.tx_dropped;
584 else if (chan->svc && chan->protocol &&
585 chan->protocol != skb->protocol) {
586 printk(KERN_INFO
587 "%s: unsupported Ethertype 0x%04X on interface %s!\n",
588 card->devname, skb->protocol, dev->name);
589 ++chan->ifstats.tx_errors;
590 } else if (chan->protocol == ETH_P_IP) {
591 switch (chan->state) {
592 case WAN_DISCONNECTED:
593 if (chan_connect(dev)) {
594 netif_stop_queue(dev);
595 return -EBUSY;
597 /* fall thru */
598 case WAN_CONNECTED:
599 reset_timer(dev);
600 dev->trans_start = jiffies;
601 netif_stop_queue(dev);
603 if (chan_send(dev, skb))
604 return -EBUSY;
606 break;
607 default:
608 ++chan->ifstats.tx_dropped;
609 ++card->wandev.stats.tx_dropped;
611 } else { /* chan->protocol == ETH_P_X25 */
612 switch (skb->data[0]) {
613 case 0: break;
614 case 1: /* Connect request */
615 chan_connect(dev);
616 goto free_packet;
617 case 2: /* Disconnect request */
618 chan_disconnect(dev);
619 goto free_packet;
620 default:
621 printk(KERN_INFO
622 "%s: unknown %d x25-iface request on %s!\n",
623 card->devname, skb->data[0], dev->name);
624 ++chan->ifstats.tx_errors;
625 goto free_packet;
628 skb_pull(skb, 1); /* Remove control byte */
629 reset_timer(dev);
630 dev->trans_start = jiffies;
631 netif_stop_queue(dev);
633 if (chan_send(dev, skb)) {
634 /* prepare for future retransmissions */
635 skb_push(skb, 1);
636 return -EBUSY;
640 free_packet:
641 dev_kfree_skb(skb);
643 return 0;
646 /* Get Ethernet-style interface statistics.
647 * Return a pointer to struct net_device_stats */
648 static struct net_device_stats *if_stats (struct net_device *dev)
650 x25_channel_t *chan = dev->priv;
652 return chan ? &chan->ifstats : NULL;
655 /* Interrupt Handlers */
656 /* X.25 Interrupt Service Routine. */
657 static void cyx_isr (cycx_t *card)
659 TX25Cmd cmd;
660 u16 z = 0;
662 card->in_isr = 1;
663 card->buff_int_mode_unbusy = 0;
664 cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
666 switch (cmd.command) {
667 case X25_DATA_INDICATION:
668 rx_intr(card, &cmd);
669 break;
670 case X25_ACK_FROM_VC:
671 tx_intr(card, &cmd);
672 break;
673 case X25_LOG:
674 log_intr(card, &cmd);
675 break;
676 case X25_STATISTIC:
677 stat_intr(card, &cmd);
678 break;
679 case X25_CONNECT_CONFIRM:
680 connect_confirm_intr(card, &cmd);
681 break;
682 case X25_CONNECT_INDICATION:
683 connect_intr(card, &cmd);
684 break;
685 case X25_DISCONNECT_INDICATION:
686 disconnect_intr(card, &cmd);
687 break;
688 case X25_DISCONNECT_CONFIRM:
689 disconnect_confirm_intr(card, &cmd);
690 break;
691 case X25_LINE_ON:
692 cyclomx_set_state(card, WAN_CONNECTED);
693 break;
694 case X25_LINE_OFF:
695 cyclomx_set_state(card, WAN_DISCONNECTED);
696 break;
697 default:
698 spur_intr(card, &cmd); /* unwanted interrupt */
701 cycx_poke(&card->hw, 0, &z, sizeof(z));
702 cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
703 card->in_isr = 0;
706 /* Transmit interrupt handler.
707 * o Release socket buffer
708 * o Clear 'tbusy' flag */
709 static void tx_intr (cycx_t *card, TX25Cmd *cmd)
711 struct net_device *dev;
712 wan_device_t *wandev = &card->wandev;
713 u8 lcn;
715 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
717 /* unbusy device and then dev_tint(); */
718 if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL) {
719 card->buff_int_mode_unbusy = 1;
720 netif_wake_queue(dev);
721 } else
722 printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n",
723 card->devname, lcn);
726 /* Receive interrupt handler.
727 * This routine handles fragmented IP packets using M-bit according to the
728 * RFC1356.
729 * o map logical channel number to network interface.
730 * o allocate socket buffer or append received packet to the existing one.
731 * o if M-bit is reset (i.e. it's the last packet in a sequence) then
732 * decapsulate packet and pass socket buffer to the protocol stack.
734 * Notes:
735 * 1. When allocating a socket buffer, if M-bit is set then more data is
736 * coming and we have to allocate buffer for the maximum IP packet size
737 * expected on this channel.
738 * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
739 * socket buffers available) the whole packet sequence must be discarded. */
740 static void rx_intr (cycx_t *card, TX25Cmd *cmd)
742 wan_device_t *wandev = &card->wandev;
743 struct net_device *dev;
744 x25_channel_t *chan;
745 struct sk_buff *skb;
746 u8 bitm, lcn;
747 int pktlen = cmd->len - 5;
749 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
750 cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
751 bitm &= 0x10;
753 if ((dev = get_dev_by_lcn(wandev, lcn)) == NULL) {
754 /* Invalid channel, discard packet */
755 printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
756 card->devname, lcn);
757 return;
760 chan = dev->priv;
761 reset_timer(dev);
763 if (chan->drop_sequence) {
764 if (!bitm)
765 chan->drop_sequence = 0;
766 else
767 return;
770 if ((skb = chan->rx_skb) == NULL) {
771 /* Allocate new socket buffer */
772 int bufsize = bitm ? dev->mtu : pktlen;
774 if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
775 bufsize +
776 dev->hard_header_len)) == NULL) {
777 printk(KERN_INFO "%s: no socket buffers available!\n",
778 card->devname);
779 chan->drop_sequence = 1;
780 ++chan->ifstats.rx_dropped;
781 return;
784 if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
785 /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
786 skb_put(skb, 1);
788 skb->dev = dev;
789 skb->protocol = htons(chan->protocol);
790 chan->rx_skb = skb;
793 if (skb_tailroom(skb) < pktlen) {
794 /* No room for the packet. Call off the whole thing! */
795 dev_kfree_skb(skb);
796 chan->rx_skb = NULL;
798 if (bitm)
799 chan->drop_sequence = 1;
801 printk(KERN_INFO "%s: unexpectedly long packet sequence "
802 "on interface %s!\n", card->devname, dev->name);
803 ++chan->ifstats.rx_length_errors;
804 return;
807 /* Append packet to the socket buffer */
808 cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
810 if (bitm)
811 return; /* more data is coming */
813 dev->last_rx = jiffies; /* timestamp */
814 chan->rx_skb = NULL; /* dequeue packet */
816 ++chan->ifstats.rx_packets;
817 chan->ifstats.rx_bytes += skb->len;
819 skb->mac.raw = skb->data;
820 netif_rx(skb);
823 /* Connect interrupt handler. */
824 static void connect_intr (cycx_t *card, TX25Cmd *cmd)
826 wan_device_t *wandev = &card->wandev;
827 struct net_device *dev = NULL;
828 x25_channel_t *chan;
829 u8 d[32],
830 loc[24],
831 rem[24];
832 u8 lcn, sizeloc, sizerem;
834 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
835 cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
836 cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
838 sizerem = sizeloc >> 4;
839 sizeloc &= 0x0F;
841 loc[0] = rem[0] = '\0';
843 if (sizeloc)
844 nibble_to_byte(d, loc, sizeloc, 0);
846 if (sizerem)
847 nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
849 dprintk(KERN_INFO "connect_intr:lcn=%d, local=%s, remote=%s\n",
850 lcn, loc, rem);
852 if ((dev = get_dev_by_dte_addr(wandev, rem)) == NULL) {
853 /* Invalid channel, discard packet */
854 printk(KERN_INFO "%s: connect not expected: remote %s!\n",
855 card->devname, rem);
856 return;
859 chan = dev->priv;
860 chan->lcn = lcn;
861 x25_connect_response(card, chan);
862 set_chan_state(dev, WAN_CONNECTED);
865 /* Connect confirm interrupt handler. */
866 static void connect_confirm_intr (cycx_t *card, TX25Cmd *cmd)
868 wan_device_t *wandev = &card->wandev;
869 struct net_device *dev;
870 x25_channel_t *chan;
871 u8 lcn, key;
873 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
874 cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
875 dprintk(KERN_INFO "%s: connect_confirm_intr:lcn=%d, key=%d\n",
876 card->devname, lcn, key);
878 if ((dev = get_dev_by_lcn(wandev, -key)) == NULL) {
879 /* Invalid channel, discard packet */
880 clear_bit(--key, (void*)&card->u.x.connection_keys);
881 printk(KERN_INFO "%s: connect confirm not expected: lcn %d, "
882 "key=%d!\n", card->devname, lcn, key);
883 return;
886 clear_bit(--key, (void*)&card->u.x.connection_keys);
887 chan = dev->priv;
888 chan->lcn = lcn;
889 set_chan_state(dev, WAN_CONNECTED);
892 /* Disconnect confirm interrupt handler. */
893 static void disconnect_confirm_intr (cycx_t *card, TX25Cmd *cmd)
895 wan_device_t *wandev = &card->wandev;
896 struct net_device *dev;
897 u8 lcn;
899 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
900 dprintk(KERN_INFO "%s: disconnect_confirm_intr:lcn=%d\n",
901 card->devname, lcn);
902 if ((dev = get_dev_by_lcn(wandev, lcn)) == NULL) {
903 /* Invalid channel, discard packet */
904 printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n",
905 card->devname, lcn);
906 return;
909 set_chan_state(dev, WAN_DISCONNECTED);
912 /* disconnect interrupt handler. */
913 static void disconnect_intr (cycx_t *card, TX25Cmd *cmd)
915 wan_device_t *wandev = &card->wandev;
916 struct net_device *dev;
917 u8 lcn;
919 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
920 dprintk(KERN_INFO "disconnect_intr:lcn=%d\n", lcn);
922 if ((dev = get_dev_by_lcn(wandev, lcn)) != NULL) {
923 x25_channel_t *chan = dev->priv;
925 x25_disconnect_response(card, chan->link, lcn);
926 set_chan_state(dev, WAN_DISCONNECTED);
927 } else
928 x25_disconnect_response(card, 0, lcn);
931 /* LOG interrupt handler. */
932 static void log_intr (cycx_t *card, TX25Cmd *cmd)
934 #if CYCLOMX_X25_DEBUG
935 char bf[20];
936 u16 size, toread, link, msg_code;
937 u8 code, routine;
939 cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
940 cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
941 cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
942 /* at most 20 bytes are available... thanks to Daniela :) */
943 toread = size < 20 ? size : 20;
944 cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
945 cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
946 cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
948 printk(KERN_INFO "cyx_isr: X25_LOG (0x4500) indic.:\n");
949 printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf);
950 printk(KERN_INFO "Log message code=0x%X\n", msg_code);
951 printk(KERN_INFO "Link=%d\n", link);
952 printk(KERN_INFO "log code=0x%X\n", code);
953 printk(KERN_INFO "log routine=0x%X\n", routine);
954 printk(KERN_INFO "Message size=%d\n", size);
955 hex_dump("Message", bf, toread);
956 #endif
959 /* STATISTIC interrupt handler. */
960 static void stat_intr (cycx_t *card, TX25Cmd *cmd)
962 cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
963 sizeof(card->u.x.stats));
964 hex_dump("stat_intr", (unsigned char*)&card->u.x.stats,
965 sizeof(card->u.x.stats));
966 x25_dump_stats(&card->u.x.stats);
967 wake_up_interruptible(&card->wait_stats);
970 /* Spurious interrupt handler.
971 * o print a warning
972 * If number of spurious interrupts exceeded some limit, then ??? */
973 static void spur_intr (cycx_t *card, TX25Cmd *cmd)
975 printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n",
976 card->devname, cmd->command);
978 #ifdef CYCLOMX_X25_DEBUG
979 static void hex_dump(char *msg, unsigned char *p, int len)
981 unsigned char hex[1024],
982 * phex = hex;
984 if (len >= (sizeof(hex) / 2))
985 len = (sizeof(hex) / 2) - 1;
987 while (len--) {
988 sprintf(phex, "%02x", *p++);
989 phex += 2;
992 printk(KERN_INFO "%s: %s\n", msg, hex);
994 #endif
996 /* Cyclom 2X Firmware-Specific Functions */
997 /* Exec X.25 command. */
998 static int x25_exec (cycx_t *card, int command, int link,
999 void *d1, int len1, void *d2, int len2)
1001 TX25Cmd c;
1002 unsigned long flags;
1003 u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
1004 u8 retry = MAX_CMD_RETRY;
1005 int err = 0;
1007 c.command = command;
1008 c.link = link;
1009 c.len = len1 + len2;
1011 spin_lock_irqsave(&card->u.x.lock, flags);
1013 /* write command */
1014 cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
1016 /* write X.25 data */
1017 if (d1) {
1018 cycx_poke(&card->hw, addr, d1, len1);
1020 if (d2) {
1021 if (len2 > 254) {
1022 u32 addr1 = 0xA00 + 0x400 * link;
1024 cycx_poke(&card->hw, addr + len1, d2, 249);
1025 cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
1026 len2 - 249);
1027 } else
1028 cycx_poke(&card->hw, addr + len1, d2, len2);
1032 /* generate interruption, executing command */
1033 cycx_intr(&card->hw);
1035 /* wait till card->mbox == 0 */
1036 do {
1037 err = cycx_exec(card->mbox);
1038 } while (retry-- && err);
1040 spin_unlock_irqrestore(&card->u.x.lock, flags);
1042 return err;
1045 /* Configure adapter. */
1046 static int x25_configure (cycx_t *card, TX25Config *conf)
1048 struct {
1049 u16 nlinks;
1050 TX25Config conf[2];
1051 } x25_cmd_conf;
1053 memset (&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1054 x25_cmd_conf.nlinks = 2;
1055 x25_cmd_conf.conf[0] = *conf;
1056 /* FIXME: we need to find a way in the wanrouter framework
1057 to configure the second link, for now lets use it
1058 with the same config from the first link, fixing
1059 the interface type to RS232, the speed in 38400 and
1060 the clock to external */
1061 x25_cmd_conf.conf[1] = *conf;
1062 x25_cmd_conf.conf[1].link = 1;
1063 x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1064 x25_cmd_conf.conf[1].clock = 8;
1065 x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1067 x25_dump_config(&x25_cmd_conf.conf[0]);
1068 x25_dump_config(&x25_cmd_conf.conf[1]);
1070 return x25_exec(card, X25_CONFIG, 0,
1071 &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1074 /* Get protocol statistics. */
1075 static int x25_get_stats (cycx_t *card)
1077 /* the firmware expects 20 in the size field!!!
1078 thanks to Daniela */
1079 int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1081 if (err)
1082 return err;
1084 interruptible_sleep_on(&card->wait_stats);
1086 if (signal_pending(current))
1087 return -EINTR;
1089 card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1090 card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1091 card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1092 card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1093 card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1094 card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1095 card->wandev.stats.rx_dropped = 0; /* not available from fw */
1096 card->wandev.stats.rx_errors = 0; /* not available from fw */
1097 card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1098 card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1099 card->wandev.stats.tx_dropped = 0; /* not available from fw */
1100 card->wandev.stats.collisions = 0; /* not available from fw */
1101 card->wandev.stats.tx_errors = 0; /* not available from fw */
1103 x25_dump_devs(&card->wandev);
1105 return 0;
1108 /* return the number of nibbles */
1109 static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1111 int i = 0;
1113 if (*nibble && *s) {
1114 d[i] |= *s++ - '0';
1115 *nibble = 0;
1116 ++i;
1119 while (*s) {
1120 d[i] = (*s - '0') << 4;
1121 if (*(s + 1))
1122 d[i] |= *(s + 1) - '0';
1123 else {
1124 *nibble = 1;
1125 break;
1127 ++i;
1128 s += 2;
1131 return i;
1134 static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1136 if (nibble) {
1137 *d++ = '0' + (*s++ & 0x0F);
1138 --len;
1141 while (len) {
1142 *d++ = '0' + (*s >> 4);
1144 if (--len) {
1145 *d++ = '0' + (*s & 0x0F);
1146 --len;
1147 } else break;
1149 ++s;
1152 *d = '\0';
1155 /* Place X.25 call. */
1156 static int x25_place_call (cycx_t *card, x25_channel_t *chan)
1158 int err = 0,
1159 len;
1160 char d[64],
1161 nibble = 0,
1162 mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1163 remotelen = strlen(chan->addr);
1164 u8 key;
1166 if (card->u.x.connection_keys == ~0UL) {
1167 printk(KERN_INFO "%s: too many simultaneous connection "
1168 "requests!\n", card->devname);
1169 return -EAGAIN;
1172 key = ffz(card->u.x.connection_keys);
1173 set_bit(key, (void*)&card->u.x.connection_keys);
1174 ++key;
1175 dprintk(KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1176 memset(d, 0, sizeof(d));
1177 d[1] = key; /* user key */
1178 d[2] = 0x10;
1179 d[4] = 0x0B;
1181 len = byte_to_nibble(chan->addr, d + 6, &nibble);
1183 if (chan->local_addr)
1184 len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
1186 if (nibble)
1187 ++len;
1189 d[5] = mylen << 4 | remotelen;
1190 d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
1192 if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1193 &d, 7 + len + 1, NULL, 0)) != 0)
1194 clear_bit(--key, (void*)&card->u.x.connection_keys);
1195 else
1196 chan->lcn = -key;
1198 return err;
1201 /* Place X.25 CONNECT RESPONSE. */
1202 static int x25_connect_response (cycx_t *card, x25_channel_t *chan)
1204 u8 d[8];
1206 memset(d, 0, sizeof(d));
1207 d[0] = d[3] = chan->lcn;
1208 d[2] = 0x10;
1209 d[4] = 0x0F;
1210 d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
1212 return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
1215 /* Place X.25 DISCONNECT RESPONSE. */
1216 static int x25_disconnect_response (cycx_t *card, u8 link, u8 lcn)
1218 char d[5];
1220 memset(d, 0, sizeof(d));
1221 d[0] = d[3] = lcn;
1222 d[2] = 0x10;
1223 d[4] = 0x17;
1225 return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
1228 /* Clear X.25 call. */
1229 static int x25_clear_call (cycx_t *card, u8 link, u8 lcn, u8 cause, u8 diagn)
1231 u8 d[7];
1233 memset(d, 0, sizeof(d));
1234 d[0] = d[3] = lcn;
1235 d[2] = 0x10;
1236 d[4] = 0x13;
1237 d[5] = cause;
1238 d[6] = diagn;
1240 return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
1243 /* Send X.25 data packet. */
1244 static int x25_send (cycx_t *card, u8 link, u8 lcn, u8 bitm, int len, void *buf)
1246 u8 d[] = "?\xFF\x10??";
1248 d[0] = d[3] = lcn;
1249 d[4] = bitm;
1251 return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
1254 /* Miscellaneous */
1255 /* Find network device by its channel number. */
1256 static struct net_device *get_dev_by_lcn (wan_device_t *wandev, s16 lcn)
1258 struct net_device *dev = wandev->dev;
1259 x25_channel_t *chan;
1261 while (dev) {
1262 if (chan->lcn == lcn)
1263 break;
1264 dev = chan->slave;
1266 return dev;
1269 /* Find network device by its remote dte address. */
1270 static struct net_device *get_dev_by_dte_addr (wan_device_t *wandev, char *dte)
1272 struct net_device *dev = wandev->dev;
1273 x25_channel_t *chan;
1275 while (dev) {
1276 if (!strcmp(chan->addr, dte))
1277 break;
1278 dev = chan->slave;
1280 return dev;
1283 /* Initiate connection on the logical channel.
1284 * o for PVC we just get channel configuration
1285 * o for SVCs place an X.25 call
1287 * Return: 0 connected
1288 * >0 connection in progress
1289 * <0 failure */
1290 static int chan_connect (struct net_device *dev)
1292 x25_channel_t *chan = dev->priv;
1293 cycx_t *card = chan->card;
1295 if (chan->svc) {
1296 if (!chan->addr[0])
1297 return -EINVAL; /* no destination address */
1299 dprintk(KERN_INFO "%s: placing X.25 call to %s...\n",
1300 card->devname, chan->addr);
1302 if (x25_place_call(card, chan))
1303 return -EIO;
1305 set_chan_state(dev, WAN_CONNECTING);
1306 return 1;
1307 } else
1308 set_chan_state(dev, WAN_CONNECTED);
1310 return 0;
1313 /* Disconnect logical channel.
1314 * o if SVC then clear X.25 call */
1315 static void chan_disconnect (struct net_device *dev)
1317 x25_channel_t *chan = dev->priv;
1319 if (chan->svc) {
1320 x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1321 set_chan_state(dev, WAN_DISCONNECTING);
1322 } else
1323 set_chan_state(dev, WAN_DISCONNECTED);
1326 /* Called by kernel timer */
1327 static void chan_timer (unsigned long d)
1329 struct net_device *dev = (struct net_device *)d;
1330 x25_channel_t *chan = dev->priv;
1332 if (chan->state == WAN_CONNECTED)
1333 chan_disconnect(dev);
1334 else
1335 printk(KERN_ERR "%s: chan_timer for svc (%s) not connected!\n",
1336 chan->card->devname, dev->name);
1339 /* Set logical channel state. */
1340 static void set_chan_state (struct net_device *dev, u8 state)
1342 x25_channel_t *chan = dev->priv;
1343 cycx_t *card = chan->card;
1344 u32 flags = 0;
1345 char *string_state = NULL;
1347 spin_lock_irqsave(&card->lock, flags);
1349 if (chan->state != state) {
1350 if (chan->svc && chan->state == WAN_CONNECTED)
1351 del_timer(&chan->timer);
1353 switch (state) {
1354 case WAN_CONNECTED:
1355 string_state = "connected!";
1356 *(u16*)dev->dev_addr = htons(chan->lcn);
1357 netif_wake_queue(dev);
1358 reset_timer(dev);
1360 if (chan->protocol == ETH_P_X25)
1361 chan_x25_send_event(dev, 1);
1363 break;
1365 case WAN_CONNECTING:
1366 string_state = "connecting...";
1367 break;
1369 case WAN_DISCONNECTING:
1370 string_state = "disconnecting...";
1371 break;
1373 case WAN_DISCONNECTED:
1374 string_state = "disconnected!";
1376 if (chan->svc) {
1377 *(unsigned short*)dev->dev_addr = 0;
1378 chan->lcn = 0;
1381 if (chan->protocol == ETH_P_X25)
1382 chan_x25_send_event(dev, 2);
1384 netif_wake_queue(dev);
1385 break;
1388 printk (KERN_INFO "%s: interface %s %s\n", card->devname,
1389 dev->name, string_state);
1390 chan->state = state;
1393 spin_unlock_irqrestore(&card->lock, flags);
1396 /* Send packet on a logical channel.
1397 * When this function is called, tx_skb field of the channel data space
1398 * points to the transmit socket buffer. When transmission is complete,
1399 * release socket buffer and reset 'tbusy' flag.
1401 * Return: 0 - transmission complete
1402 * 1 - busy
1404 * Notes:
1405 * 1. If packet length is greater than MTU for this channel, we'll fragment
1406 * the packet into 'complete sequence' using M-bit.
1407 * 2. When transmission is complete, an event notification should be issued
1408 * to the router. */
1409 static int chan_send (struct net_device *dev, struct sk_buff *skb)
1411 x25_channel_t *chan = dev->priv;
1412 cycx_t *card = chan->card;
1413 int bitm = 0; /* final packet */
1414 unsigned len = skb->len;
1416 if (skb->len > card->wandev.mtu) {
1417 len = card->wandev.mtu;
1418 bitm = 0x10; /* set M-bit (more data) */
1421 if (x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1422 return 1;
1424 if (bitm) {
1425 skb_pull(skb, len);
1426 return 1;
1429 ++chan->ifstats.tx_packets;
1430 chan->ifstats.tx_bytes += len;
1432 return 0;
1435 /* Send event (connection, disconnection, etc) to X.25 socket layer */
1437 static void chan_x25_send_event(struct net_device *dev, u8 event)
1439 struct sk_buff *skb;
1440 unsigned char *ptr;
1442 if ((skb = dev_alloc_skb(1)) == NULL) {
1443 printk(KERN_ERR __FUNCTION__ ": out of memory\n");
1444 return;
1447 ptr = skb_put(skb, 1);
1448 *ptr = event;
1450 skb->dev = dev;
1451 skb->protocol = htons(ETH_P_X25);
1452 skb->mac.raw = skb->data;
1453 skb->pkt_type = PACKET_HOST;
1455 netif_rx(skb);
1458 /* Convert line speed in bps to a number used by cyclom 2x code. */
1459 static u8 bps_to_speed_code (u32 bps)
1461 u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1463 if (bps >= 512000) number = 8;
1464 else if (bps >= 256000) number = 7;
1465 else if (bps >= 64000) number = 6;
1466 else if (bps >= 38400) number = 5;
1467 else if (bps >= 19200) number = 4;
1468 else if (bps >= 9600) number = 3;
1469 else if (bps >= 4800) number = 2;
1470 else if (bps >= 2400) number = 1;
1472 return number;
1475 /* log base 2 */
1476 static u8 log2 (u32 n)
1478 u8 log = 0;
1480 if (!n)
1481 return 0;
1483 while (n > 1) {
1484 n >>= 1;
1485 ++log;
1488 return log;
1491 /* Convert decimal string to unsigned integer.
1492 * If len != 0 then only 'len' characters of the string are converted. */
1493 static unsigned dec_to_uint (u8 *str, int len)
1495 unsigned val = 0;
1497 if (!len)
1498 len = strlen(str);
1500 for (; len && is_digit(*str); ++str, --len)
1501 val = (val * 10) + (*str - (unsigned) '0');
1503 return val;
1506 static void reset_timer(struct net_device *dev)
1508 x25_channel_t *chan = dev->priv;
1510 if (chan->svc) {
1511 del_timer(&chan->timer);
1512 chan->timer.expires = jiffies + chan->idle_tmout * HZ;
1513 add_timer(&chan->timer);
1516 #ifdef CYCLOMX_X25_DEBUG
1517 static void x25_dump_config(TX25Config *conf)
1519 printk(KERN_INFO "X.25 configuration\n");
1520 printk(KERN_INFO "-----------------\n");
1521 printk(KERN_INFO "link number=%d\n", conf->link);
1522 printk(KERN_INFO "line speed=%d\n", conf->speed);
1523 printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1524 printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1525 printk(KERN_INFO "level 2 window=%d\n", conf->n2win);
1526 printk(KERN_INFO "level 3 window=%d\n", conf->n3win);
1527 printk(KERN_INFO "# logical channels=%d\n", conf->nvc);
1528 printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1529 printk(KERN_INFO "my address=%d\n", conf->locaddr);
1530 printk(KERN_INFO "remote address=%d\n", conf->remaddr);
1531 printk(KERN_INFO "t1=%d seconds\n", conf->t1);
1532 printk(KERN_INFO "t2=%d seconds\n", conf->t2);
1533 printk(KERN_INFO "t21=%d seconds\n", conf->t21);
1534 printk(KERN_INFO "# PVCs=%d\n", conf->npvc);
1535 printk(KERN_INFO "t23=%d seconds\n", conf->t23);
1536 printk(KERN_INFO "flags=0x%x\n", conf->flags);
1539 static void x25_dump_stats(TX25Stats *stats)
1541 printk(KERN_INFO "X.25 statistics\n");
1542 printk(KERN_INFO "--------------\n");
1543 printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1544 printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1545 printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1546 printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1547 printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1548 printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1549 printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1550 printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1551 printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1552 printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1555 static void x25_dump_devs(wan_device_t *wandev)
1557 struct net_device *dev = wandev->dev;
1559 printk(KERN_INFO "X.25 dev states\n");
1560 printk(KERN_INFO "name: addr: txoff: protocol:\n");
1561 printk(KERN_INFO "---------------------------------------\n");
1563 while(dev) {
1564 x25_channel_t *chan = dev->priv;
1566 printk(KERN_INFO "%-5.5s %-15.15s %d ETH_P_%s\n",
1567 chan->name, chan->addr, netif_queue_stopped(dev),
1568 chan->protocol == ETH_P_IP ? "IP" : "X25");
1569 dev = chan->slave;
1573 #endif /* CYCLOMX_X25_DEBUG */
1574 /* End */