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-2003 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 * 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
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,
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
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
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,
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
54 * 1999/01/05 acme pktlen now (correctly) uses log2 (value
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.
79 #define CYCLOMX_X25_DEBUG 1
81 #include <linux/errno.h> /* return codes */
82 #include <linux/if_arp.h> /* ARPHRD_HWX25 */
83 #include <linux/kernel.h> /* printk(), and other useful stuff */
84 #include <linux/module.h>
85 #include <linux/string.h> /* inline memset(), etc. */
86 #include <linux/slab.h> /* kmalloc(), kfree() */
87 #include <linux/stddef.h> /* offsetof(), etc. */
88 #include <linux/wanrouter.h> /* WAN router definitions */
90 #include <asm/byteorder.h> /* htons(), etc. */
92 #include <linux/cyclomx.h> /* Cyclom 2X common user API definitions */
93 #include <linux/cycx_x25.h> /* X.25 firmware API definitions */
95 /* Defines & Macros */
96 #define CYCX_X25_MAX_CMD_RETRY 5
97 #define CYCX_X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
100 /* This is an extension of the 'struct net_device' we create for each network
101 interface to keep the rest of X.25 channel-specific data. */
102 struct cycx_x25_channel {
103 /* This member must be first. */
104 struct net_device *slave; /* WAN slave */
106 char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
107 char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
108 char *local_addr; /* local media address, ASCIIZ -
109 svc thru crossover cable */
110 s16 lcn; /* logical channel number/conn.req.key*/
112 struct timer_list timer; /* timer used for svc channel disc. */
113 u16 protocol; /* ethertype, 0 - multiplexed */
114 u8 svc; /* 0 - permanent, 1 - switched */
115 u8 state; /* channel state */
116 u8 drop_sequence; /* mark sequence for dropping */
117 u32 idle_tmout; /* sec, before disconnecting */
118 struct sk_buff *rx_skb; /* receive socket buffer */
119 struct cycx_device *card; /* -> owner */
120 struct net_device_stats ifstats;/* interface statistics */
123 /* Function Prototypes */
124 /* WAN link driver entry points. These are called by the WAN router module. */
125 static int cycx_wan_update(struct wan_device *wandev),
126 cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
128 cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
130 /* Network device interface */
131 static int cycx_netdevice_init(struct net_device *dev),
132 cycx_netdevice_open(struct net_device *dev),
133 cycx_netdevice_stop(struct net_device *dev),
134 cycx_netdevice_hard_header(struct sk_buff *skb,
135 struct net_device *dev, u16 type,
136 void *daddr, void *saddr, unsigned len),
137 cycx_netdevice_rebuild_header(struct sk_buff *skb),
138 cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
139 struct net_device *dev);
141 static struct net_device_stats *
142 cycx_netdevice_get_stats(struct net_device *dev);
144 /* Interrupt handlers */
145 static void cycx_x25_irq_handler(struct cycx_device *card),
146 cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
147 cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
148 cycx_x25_irq_log(struct cycx_device *card,
149 struct cycx_x25_cmd *cmd),
150 cycx_x25_irq_stat(struct cycx_device *card,
151 struct cycx_x25_cmd *cmd),
152 cycx_x25_irq_connect_confirm(struct cycx_device *card,
153 struct cycx_x25_cmd *cmd),
154 cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
155 struct cycx_x25_cmd *cmd),
156 cycx_x25_irq_connect(struct cycx_device *card,
157 struct cycx_x25_cmd *cmd),
158 cycx_x25_irq_disconnect(struct cycx_device *card,
159 struct cycx_x25_cmd *cmd),
160 cycx_x25_irq_spurious(struct cycx_device *card,
161 struct cycx_x25_cmd *cmd);
163 /* X.25 firmware interface functions */
164 static int cycx_x25_configure(struct cycx_device *card,
165 struct cycx_x25_config *conf),
166 cycx_x25_get_stats(struct cycx_device *card),
167 cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
169 cycx_x25_connect_response(struct cycx_device *card,
170 struct cycx_x25_channel *chan),
171 cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
174 /* channel functions */
175 static int cycx_x25_chan_connect(struct net_device *dev),
176 cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb);
178 static void cycx_x25_chan_disconnect(struct net_device *dev),
179 cycx_x25_chan_send_event(struct net_device *dev, u8 event);
181 /* Miscellaneous functions */
182 static void cycx_x25_set_chan_state(struct net_device *dev, u8 state),
183 cycx_x25_chan_timer(unsigned long d);
185 static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble),
186 reset_timer(struct net_device *dev);
188 static u8 bps_to_speed_code(u32 bps);
189 static u8 cycx_log2(u32 n);
191 static unsigned dec_to_uint(u8 *str, int len);
193 static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
195 static struct net_device *
196 cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
198 #ifdef CYCLOMX_X25_DEBUG
199 static void hex_dump(char *msg, unsigned char *p, int len);
200 static void cycx_x25_dump_config(struct cycx_x25_config *conf);
201 static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
202 static void cycx_x25_dump_devs(struct wan_device *wandev);
204 #define hex_dump(msg, p, len)
205 #define cycx_x25_dump_config(conf)
206 #define cycx_x25_dump_stats(stats)
207 #define cycx_x25_dump_devs(wandev)
209 /* Public Functions */
211 /* X.25 Protocol Initialization routine.
213 * This routine is called by the main Cyclom 2X module during setup. At this
214 * point adapter is completely initialized and X.25 firmware is running.
215 * o configure adapter
216 * o initialize protocol-specific fields of the adapter data space.
220 int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
222 struct cycx_x25_config cfg;
224 /* Verify configuration ID */
225 if (conf->config_id != WANCONFIG_X25) {
226 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
227 card->devname, conf->config_id);
231 /* Initialize protocol-specific fields */
232 card->mbox = card->hw.dpmbase + X25_MBOX_OFFS;
233 card->u.x.connection_keys = 0;
234 card->u.x.lock = SPIN_LOCK_UNLOCKED;
236 /* Configure adapter. Here we set reasonable defaults, then parse
237 * device configuration structure and set configuration options.
238 * Most configuration options are verified and corrected (if
239 * necessary) since we can't rely on the adapter to do so and don't
240 * want it to fail either. */
241 memset(&cfg, 0, sizeof(cfg));
243 cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
244 cfg.speed = bps_to_speed_code(conf->bps);
250 cfg.flags = 0x02; /* default = V35 */
251 cfg.t1 = 10; /* line carrier timeout */
252 cfg.t2 = 29; /* tx timeout */
253 cfg.t21 = 180; /* CALL timeout */
254 cfg.t23 = 180; /* CLEAR timeout */
257 if (!conf->mtu || conf->mtu >= 512)
258 card->wandev.mtu = 512;
259 else if (conf->mtu >= 256)
260 card->wandev.mtu = 256;
261 else if (conf->mtu >= 128)
262 card->wandev.mtu = 128;
264 card->wandev.mtu = 64;
266 cfg.pktlen = cycx_log2(card->wandev.mtu);
268 if (conf->station == WANOPT_DTE) {
269 cfg.locaddr = 3; /* DTE */
270 cfg.remaddr = 1; /* DCE */
272 cfg.locaddr = 1; /* DCE */
273 cfg.remaddr = 3; /* DTE */
276 if (conf->interface == WANOPT_RS232)
277 cfg.flags = 0; /* FIXME just reset the 2nd bit */
279 if (conf->u.x25.hi_pvc) {
280 card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
281 card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
284 if (conf->u.x25.hi_svc) {
285 card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
286 card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
289 if (card->u.x.lo_pvc == 255)
292 cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
294 cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
296 if (conf->u.x25.hdlc_window)
297 cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
299 if (conf->u.x25.pkt_window)
300 cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
303 cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
306 cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
308 if (conf->u.x25.t11_t21)
309 cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
311 if (conf->u.x25.t13_t23)
312 cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
315 cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
317 /* initialize adapter */
318 if (cycx_x25_configure(card, &cfg))
321 /* Initialize protocol-specific fields of adapter data space */
322 card->wandev.bps = conf->bps;
323 card->wandev.interface = conf->interface;
324 card->wandev.clocking = conf->clocking;
325 card->wandev.station = conf->station;
326 card->isr = cycx_x25_irq_handler;
328 card->wandev.update = cycx_wan_update;
329 card->wandev.new_if = cycx_wan_new_if;
330 card->wandev.del_if = cycx_wan_del_if;
331 card->wandev.state = WAN_DISCONNECTED;
336 /* WAN Device Driver Entry Points */
337 /* Update device status & statistics. */
338 static int cycx_wan_update(struct wan_device *wandev)
341 if (!wandev || !wandev->private)
344 if (wandev->state == WAN_UNCONFIGURED)
347 cycx_x25_get_stats(wandev->private);
352 /* Create new logical channel.
353 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
355 * o parse media- and hardware-specific configuration
356 * o make sure that a new channel can be created
357 * o allocate resources, if necessary
358 * o prepare network device structure for registration.
361 * < 0 failure (channel will not be created) */
362 static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
365 struct cycx_device *card = wandev->private;
366 struct cycx_x25_channel *chan;
369 if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
370 printk(KERN_INFO "%s: invalid interface name!\n",
375 /* allocate and initialize private data */
376 chan = kmalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL);
380 memset(chan, 0, sizeof(*chan));
381 strcpy(chan->name, conf->name);
383 chan->link = conf->port;
384 chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
386 /* only used in svc connected thru crossover cable */
387 chan->local_addr = NULL;
389 if (conf->addr[0] == '@') { /* SVC */
390 int len = strlen(conf->local_addr);
393 if (len > WAN_ADDRESS_SZ) {
394 printk(KERN_ERR "%s: %s local addr too long!\n",
395 wandev->name, chan->name);
399 chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
401 if (!chan->local_addr) {
407 strncpy(chan->local_addr, conf->local_addr,
412 strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
413 init_timer(&chan->timer);
414 chan->timer.function = cycx_x25_chan_timer;
415 chan->timer.data = (unsigned long)dev;
417 /* Set channel timeouts (default if not specified) */
418 chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
419 } else if (is_digit(conf->addr[0])) { /* PVC */
420 s16 lcn = dec_to_uint(conf->addr, 0);
422 if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
426 "%s: PVC %u is out of range on interface %s!\n",
427 wandev->name, lcn, chan->name);
431 printk(KERN_ERR "%s: invalid media address on interface %s!\n",
432 wandev->name, chan->name);
437 if (chan->local_addr)
438 kfree(chan->local_addr);
444 /* prepare network device data space for registration */
445 strcpy(dev->name, chan->name);
446 dev->init = cycx_netdevice_init;
452 /* Delete logical channel. */
453 static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
456 struct cycx_x25_channel *chan = dev->priv;
459 if (chan->local_addr)
460 kfree(chan->local_addr);
462 if (chan->state == WAN_CONNECTED)
463 del_timer(&chan->timer);
473 /* Network Device Interface */
474 /* Initialize Linux network interface.
476 * This routine is called only once for each interface, during Linux network
477 * interface registration. Returning anything but zero will fail interface
479 static int cycx_netdevice_init(struct net_device *dev)
481 struct cycx_x25_channel *chan = dev->priv;
482 struct cycx_device *card = chan->card;
483 struct wan_device *wandev = &card->wandev;
485 /* Initialize device driver entry points */
486 dev->open = cycx_netdevice_open;
487 dev->stop = cycx_netdevice_stop;
488 dev->hard_header = cycx_netdevice_hard_header;
489 dev->rebuild_header = cycx_netdevice_rebuild_header;
490 dev->hard_start_xmit = cycx_netdevice_hard_start_xmit;
491 dev->get_stats = cycx_netdevice_get_stats;
493 /* Initialize media-specific parameters */
494 dev->mtu = CYCX_X25_CHAN_MTU;
495 dev->type = ARPHRD_HWX25; /* ARP h/w type */
496 dev->hard_header_len = 0; /* media header length */
497 dev->addr_len = 0; /* hardware address length */
500 *(u16*)dev->dev_addr = htons(chan->lcn);
502 /* Initialize hardware parameters (just for reference) */
503 dev->irq = wandev->irq;
504 dev->dma = wandev->dma;
505 dev->base_addr = wandev->ioport;
506 dev->mem_start = (unsigned long)wandev->maddr;
507 dev->mem_end = (unsigned long)(wandev->maddr +
509 dev->flags |= IFF_NOARP;
511 /* Set transmit buffer queue length */
512 dev->tx_queue_len = 10;
513 SET_MODULE_OWNER(dev);
515 /* Initialize socket buffers */
516 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
521 /* Open network interface.
522 * o prevent module from unloading by incrementing use count
523 * o if link is disconnected then initiate connection
525 * Return 0 if O.k. or errno. */
526 static int cycx_netdevice_open(struct net_device *dev)
528 if (netif_running(dev))
529 return -EBUSY; /* only one open is allowed */
531 netif_start_queue(dev);
535 /* Close network interface.
537 * o if there's no more open channels then disconnect physical link. */
538 static int cycx_netdevice_stop(struct net_device *dev)
540 struct cycx_x25_channel *chan = dev->priv;
542 netif_stop_queue(dev);
544 if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
545 cycx_x25_chan_disconnect(dev);
550 /* Build media header.
551 * o encapsulate packet according to encapsulation type.
553 * The trick here is to put packet type (Ethertype) into 'protocol' field of
554 * the socket buffer, so that we don't forget it. If encapsulation fails,
555 * set skb->protocol to 0 and discard packet later.
557 * Return: media header length. */
558 static int cycx_netdevice_hard_header(struct sk_buff *skb,
559 struct net_device *dev, u16 type,
560 void *daddr, void *saddr, unsigned len)
562 skb->protocol = type;
564 return dev->hard_header_len;
567 /* * Re-build media header.
568 * Return: 1 physical address resolved.
569 * 0 physical address not resolved */
570 static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
575 /* Send a packet on a network interface.
576 * o set busy flag (marks start of the transmission).
577 * o check link state. If link is not up, then drop the packet.
578 * o check channel status. If it's down then initiate a call.
579 * o pass a packet to corresponding WAN device.
580 * o free socket buffer
582 * Return: 0 complete (socket buffer must be freed)
583 * non-0 packet may be re-transmitted (tbusy must be set)
586 * 1. This routine is called either by the protocol stack or by the "net
587 * bottom half" (with interrupts enabled).
588 * 2. Setting tbusy flag will inhibit further transmit requests from the
589 * protocol stack and can be used for flow control with protocol layer. */
590 static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
591 struct net_device *dev)
593 struct cycx_x25_channel *chan = dev->priv;
594 struct cycx_device *card = chan->card;
597 chan->protocol = skb->protocol;
599 if (card->wandev.state != WAN_CONNECTED)
600 ++chan->ifstats.tx_dropped;
601 else if (chan->svc && chan->protocol &&
602 chan->protocol != skb->protocol) {
604 "%s: unsupported Ethertype 0x%04X on interface %s!\n",
605 card->devname, skb->protocol, dev->name);
606 ++chan->ifstats.tx_errors;
607 } else if (chan->protocol == ETH_P_IP) {
608 switch (chan->state) {
609 case WAN_DISCONNECTED:
610 if (cycx_x25_chan_connect(dev)) {
611 netif_stop_queue(dev);
617 dev->trans_start = jiffies;
618 netif_stop_queue(dev);
620 if (cycx_x25_chan_send(dev, skb))
625 ++chan->ifstats.tx_dropped;
626 ++card->wandev.stats.tx_dropped;
628 } else { /* chan->protocol == ETH_P_X25 */
629 switch (skb->data[0]) {
631 case 1: /* Connect request */
632 cycx_x25_chan_connect(dev);
634 case 2: /* Disconnect request */
635 cycx_x25_chan_disconnect(dev);
639 "%s: unknown %d x25-iface request on %s!\n",
640 card->devname, skb->data[0], dev->name);
641 ++chan->ifstats.tx_errors;
645 skb_pull(skb, 1); /* Remove control byte */
647 dev->trans_start = jiffies;
648 netif_stop_queue(dev);
650 if (cycx_x25_chan_send(dev, skb)) {
651 /* prepare for future retransmissions */
663 /* Get Ethernet-style interface statistics.
664 * Return a pointer to struct net_device_stats */
665 static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
667 struct cycx_x25_channel *chan = dev->priv;
669 return chan ? &chan->ifstats : NULL;
672 /* Interrupt Handlers */
673 /* X.25 Interrupt Service Routine. */
674 static void cycx_x25_irq_handler(struct cycx_device *card)
676 struct cycx_x25_cmd cmd;
680 card->buff_int_mode_unbusy = 0;
681 cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
683 switch (cmd.command) {
684 case X25_DATA_INDICATION:
685 cycx_x25_irq_rx(card, &cmd);
687 case X25_ACK_FROM_VC:
688 cycx_x25_irq_tx(card, &cmd);
691 cycx_x25_irq_log(card, &cmd);
694 cycx_x25_irq_stat(card, &cmd);
696 case X25_CONNECT_CONFIRM:
697 cycx_x25_irq_connect_confirm(card, &cmd);
699 case X25_CONNECT_INDICATION:
700 cycx_x25_irq_connect(card, &cmd);
702 case X25_DISCONNECT_INDICATION:
703 cycx_x25_irq_disconnect(card, &cmd);
705 case X25_DISCONNECT_CONFIRM:
706 cycx_x25_irq_disconnect_confirm(card, &cmd);
709 cycx_set_state(card, WAN_CONNECTED);
712 cycx_set_state(card, WAN_DISCONNECTED);
715 cycx_x25_irq_spurious(card, &cmd);
719 cycx_poke(&card->hw, 0, &z, sizeof(z));
720 cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
724 /* Transmit interrupt handler.
725 * o Release socket buffer
726 * o Clear 'tbusy' flag */
727 static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
729 struct net_device *dev;
730 struct wan_device *wandev = &card->wandev;
733 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
735 /* unbusy device and then dev_tint(); */
736 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
738 card->buff_int_mode_unbusy = 1;
739 netif_wake_queue(dev);
741 printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n",
745 /* Receive interrupt handler.
746 * This routine handles fragmented IP packets using M-bit according to the
748 * o map logical channel number to network interface.
749 * o allocate socket buffer or append received packet to the existing one.
750 * o if M-bit is reset (i.e. it's the last packet in a sequence) then
751 * decapsulate packet and pass socket buffer to the protocol stack.
754 * 1. When allocating a socket buffer, if M-bit is set then more data is
755 * coming and we have to allocate buffer for the maximum IP packet size
756 * expected on this channel.
757 * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
758 * socket buffers available) the whole packet sequence must be discarded. */
759 static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
761 struct wan_device *wandev = &card->wandev;
762 struct net_device *dev;
763 struct cycx_x25_channel *chan;
766 int pktlen = cmd->len - 5;
768 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
769 cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
772 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
774 /* Invalid channel, discard packet */
775 printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
783 if (chan->drop_sequence) {
785 chan->drop_sequence = 0;
790 if ((skb = chan->rx_skb) == NULL) {
791 /* Allocate new socket buffer */
792 int bufsize = bitm ? dev->mtu : pktlen;
794 if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
796 dev->hard_header_len)) == NULL) {
797 printk(KERN_INFO "%s: no socket buffers available!\n",
799 chan->drop_sequence = 1;
800 ++chan->ifstats.rx_dropped;
804 if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
805 /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
809 skb->protocol = htons(chan->protocol);
813 if (skb_tailroom(skb) < pktlen) {
814 /* No room for the packet. Call off the whole thing! */
815 dev_kfree_skb_irq(skb);
819 chan->drop_sequence = 1;
821 printk(KERN_INFO "%s: unexpectedly long packet sequence "
822 "on interface %s!\n", card->devname, dev->name);
823 ++chan->ifstats.rx_length_errors;
827 /* Append packet to the socket buffer */
828 cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
831 return; /* more data is coming */
833 chan->rx_skb = NULL; /* dequeue packet */
835 ++chan->ifstats.rx_packets;
836 chan->ifstats.rx_bytes += pktlen;
838 skb->mac.raw = skb->data;
840 dev->last_rx = jiffies; /* timestamp */
843 /* Connect interrupt handler. */
844 static void cycx_x25_irq_connect(struct cycx_device *card,
845 struct cycx_x25_cmd *cmd)
847 struct wan_device *wandev = &card->wandev;
848 struct net_device *dev = NULL;
849 struct cycx_x25_channel *chan;
853 u8 lcn, sizeloc, sizerem;
855 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
856 cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
857 cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
859 sizerem = sizeloc >> 4;
862 loc[0] = rem[0] = '\0';
865 nibble_to_byte(d, loc, sizeloc, 0);
868 nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
870 dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
871 __FUNCTION__, lcn, loc, rem);
873 dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
875 /* Invalid channel, discard packet */
876 printk(KERN_INFO "%s: connect not expected: remote %s!\n",
883 cycx_x25_connect_response(card, chan);
884 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
887 /* Connect confirm interrupt handler. */
888 static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
889 struct cycx_x25_cmd *cmd)
891 struct wan_device *wandev = &card->wandev;
892 struct net_device *dev;
893 struct cycx_x25_channel *chan;
896 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
897 cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
898 dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
899 card->devname, __FUNCTION__, lcn, key);
901 dev = cycx_x25_get_dev_by_lcn(wandev, -key);
903 /* Invalid channel, discard packet */
904 clear_bit(--key, (void*)&card->u.x.connection_keys);
905 printk(KERN_INFO "%s: connect confirm not expected: lcn %d, "
906 "key=%d!\n", card->devname, lcn, key);
910 clear_bit(--key, (void*)&card->u.x.connection_keys);
913 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
916 /* Disconnect confirm interrupt handler. */
917 static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
918 struct cycx_x25_cmd *cmd)
920 struct wan_device *wandev = &card->wandev;
921 struct net_device *dev;
924 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
925 dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
926 card->devname, __FUNCTION__, lcn);
927 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
929 /* Invalid channel, discard packet */
930 printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n",
935 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
938 /* disconnect interrupt handler. */
939 static void cycx_x25_irq_disconnect(struct cycx_device *card,
940 struct cycx_x25_cmd *cmd)
942 struct wan_device *wandev = &card->wandev;
943 struct net_device *dev;
946 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
947 dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn);
949 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
951 struct cycx_x25_channel *chan = dev->priv;
953 cycx_x25_disconnect_response(card, chan->link, lcn);
954 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
956 cycx_x25_disconnect_response(card, 0, lcn);
959 /* LOG interrupt handler. */
960 static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd)
962 #if CYCLOMX_X25_DEBUG
964 u16 size, toread, link, msg_code;
967 cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
968 cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
969 cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
970 /* at most 20 bytes are available... thanks to Daniela :) */
971 toread = size < 20 ? size : 20;
972 cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
973 cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
974 cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
976 printk(KERN_INFO "cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n");
977 printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf);
978 printk(KERN_INFO "Log message code=0x%X\n", msg_code);
979 printk(KERN_INFO "Link=%d\n", link);
980 printk(KERN_INFO "log code=0x%X\n", code);
981 printk(KERN_INFO "log routine=0x%X\n", routine);
982 printk(KERN_INFO "Message size=%d\n", size);
983 hex_dump("Message", bf, toread);
987 /* STATISTIC interrupt handler. */
988 static void cycx_x25_irq_stat(struct cycx_device *card,
989 struct cycx_x25_cmd *cmd)
991 cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
992 sizeof(card->u.x.stats));
993 hex_dump("cycx_x25_irq_stat", (unsigned char*)&card->u.x.stats,
994 sizeof(card->u.x.stats));
995 cycx_x25_dump_stats(&card->u.x.stats);
996 wake_up_interruptible(&card->wait_stats);
999 /* Spurious interrupt handler.
1001 * If number of spurious interrupts exceeded some limit, then ??? */
1002 static void cycx_x25_irq_spurious(struct cycx_device *card,
1003 struct cycx_x25_cmd *cmd)
1005 printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n",
1006 card->devname, cmd->command);
1008 #ifdef CYCLOMX_X25_DEBUG
1009 static void hex_dump(char *msg, unsigned char *p, int len)
1011 unsigned char hex[1024],
1014 if (len >= (sizeof(hex) / 2))
1015 len = (sizeof(hex) / 2) - 1;
1018 sprintf(phex, "%02x", *p++);
1022 printk(KERN_INFO "%s: %s\n", msg, hex);
1026 /* Cyclom 2X Firmware-Specific Functions */
1027 /* Exec X.25 command. */
1028 static int x25_exec(struct cycx_device *card, int command, int link,
1029 void *d1, int len1, void *d2, int len2)
1031 struct cycx_x25_cmd c;
1032 unsigned long flags;
1033 u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
1034 u8 retry = CYCX_X25_MAX_CMD_RETRY;
1037 c.command = command;
1039 c.len = len1 + len2;
1041 spin_lock_irqsave(&card->u.x.lock, flags);
1044 cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
1046 /* write X.25 data */
1048 cycx_poke(&card->hw, addr, d1, len1);
1052 u32 addr1 = 0xA00 + 0x400 * link;
1054 cycx_poke(&card->hw, addr + len1, d2, 249);
1055 cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
1058 cycx_poke(&card->hw, addr + len1, d2, len2);
1062 /* generate interruption, executing command */
1063 cycx_intr(&card->hw);
1065 /* wait till card->mbox == 0 */
1067 err = cycx_exec(card->mbox);
1068 } while (retry-- && err);
1070 spin_unlock_irqrestore(&card->u.x.lock, flags);
1075 /* Configure adapter. */
1076 static int cycx_x25_configure(struct cycx_device *card,
1077 struct cycx_x25_config *conf)
1081 struct cycx_x25_config conf[2];
1084 memset(&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1085 x25_cmd_conf.nlinks = 2;
1086 x25_cmd_conf.conf[0] = *conf;
1087 /* FIXME: we need to find a way in the wanrouter framework
1088 to configure the second link, for now lets use it
1089 with the same config from the first link, fixing
1090 the interface type to RS232, the speed in 38400 and
1091 the clock to external */
1092 x25_cmd_conf.conf[1] = *conf;
1093 x25_cmd_conf.conf[1].link = 1;
1094 x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1095 x25_cmd_conf.conf[1].clock = 8;
1096 x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1098 cycx_x25_dump_config(&x25_cmd_conf.conf[0]);
1099 cycx_x25_dump_config(&x25_cmd_conf.conf[1]);
1101 return x25_exec(card, X25_CONFIG, 0,
1102 &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1105 /* Get protocol statistics. */
1106 static int cycx_x25_get_stats(struct cycx_device *card)
1108 /* the firmware expects 20 in the size field!!!
1109 thanks to Daniela */
1110 int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1115 interruptible_sleep_on(&card->wait_stats);
1117 if (signal_pending(current))
1120 card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1121 card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1122 card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1123 card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1124 card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1125 card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1126 card->wandev.stats.rx_dropped = 0; /* not available from fw */
1127 card->wandev.stats.rx_errors = 0; /* not available from fw */
1128 card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1129 card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1130 card->wandev.stats.tx_dropped = 0; /* not available from fw */
1131 card->wandev.stats.collisions = 0; /* not available from fw */
1132 card->wandev.stats.tx_errors = 0; /* not available from fw */
1134 cycx_x25_dump_devs(&card->wandev);
1139 /* return the number of nibbles */
1140 static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1144 if (*nibble && *s) {
1151 d[i] = (*s - '0') << 4;
1153 d[i] |= *(s + 1) - '0';
1165 static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1168 *d++ = '0' + (*s++ & 0x0F);
1173 *d++ = '0' + (*s >> 4);
1176 *d++ = '0' + (*s & 0x0F);
1186 /* Place X.25 call. */
1187 static int x25_place_call(struct cycx_device *card,
1188 struct cycx_x25_channel *chan)
1194 mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1195 remotelen = strlen(chan->addr);
1198 if (card->u.x.connection_keys == ~0UL) {
1199 printk(KERN_INFO "%s: too many simultaneous connection "
1200 "requests!\n", card->devname);
1204 key = ffz(card->u.x.connection_keys);
1205 set_bit(key, (void*)&card->u.x.connection_keys);
1207 dprintk(1, KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1208 memset(d, 0, sizeof(d));
1209 d[1] = key; /* user key */
1213 len = byte_to_nibble(chan->addr, d + 6, &nibble);
1215 if (chan->local_addr)
1216 len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
1221 d[5] = mylen << 4 | remotelen;
1222 d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
1224 if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1225 &d, 7 + len + 1, NULL, 0)) != 0)
1226 clear_bit(--key, (void*)&card->u.x.connection_keys);
1233 /* Place X.25 CONNECT RESPONSE. */
1234 static int cycx_x25_connect_response(struct cycx_device *card,
1235 struct cycx_x25_channel *chan)
1239 memset(d, 0, sizeof(d));
1240 d[0] = d[3] = chan->lcn;
1243 d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
1245 return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
1248 /* Place X.25 DISCONNECT RESPONSE. */
1249 static int cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
1254 memset(d, 0, sizeof(d));
1259 return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
1262 /* Clear X.25 call. */
1263 static int x25_clear_call(struct cycx_device *card, u8 link, u8 lcn, u8 cause,
1268 memset(d, 0, sizeof(d));
1275 return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
1278 /* Send X.25 data packet. */
1279 static int cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
1282 u8 d[] = "?\xFF\x10??";
1287 return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
1291 /* Find network device by its channel number. */
1292 static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
1295 struct net_device *dev = wandev->dev;
1296 struct cycx_x25_channel *chan;
1299 chan = (struct cycx_x25_channel*)dev->priv;
1301 if (chan->lcn == lcn)
1308 /* Find network device by its remote dte address. */
1309 static struct net_device *
1310 cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte)
1312 struct net_device *dev = wandev->dev;
1313 struct cycx_x25_channel *chan;
1316 chan = (struct cycx_x25_channel*)dev->priv;
1318 if (!strcmp(chan->addr, dte))
1325 /* Initiate connection on the logical channel.
1326 * o for PVC we just get channel configuration
1327 * o for SVCs place an X.25 call
1329 * Return: 0 connected
1330 * >0 connection in progress
1332 static int cycx_x25_chan_connect(struct net_device *dev)
1334 struct cycx_x25_channel *chan = dev->priv;
1335 struct cycx_device *card = chan->card;
1339 return -EINVAL; /* no destination address */
1341 dprintk(1, KERN_INFO "%s: placing X.25 call to %s...\n",
1342 card->devname, chan->addr);
1344 if (x25_place_call(card, chan))
1347 cycx_x25_set_chan_state(dev, WAN_CONNECTING);
1350 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
1355 /* Disconnect logical channel.
1356 * o if SVC then clear X.25 call */
1357 static void cycx_x25_chan_disconnect(struct net_device *dev)
1359 struct cycx_x25_channel *chan = dev->priv;
1362 x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1363 cycx_x25_set_chan_state(dev, WAN_DISCONNECTING);
1365 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
1368 /* Called by kernel timer */
1369 static void cycx_x25_chan_timer(unsigned long d)
1371 struct net_device *dev = (struct net_device *)d;
1372 struct cycx_x25_channel *chan = dev->priv;
1374 if (chan->state == WAN_CONNECTED)
1375 cycx_x25_chan_disconnect(dev);
1377 printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
1378 chan->card->devname, __FUNCTION__, dev->name);
1381 /* Set logical channel state. */
1382 static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
1384 struct cycx_x25_channel *chan = dev->priv;
1385 struct cycx_device *card = chan->card;
1386 unsigned long flags;
1387 char *string_state = NULL;
1389 spin_lock_irqsave(&card->lock, flags);
1391 if (chan->state != state) {
1392 if (chan->svc && chan->state == WAN_CONNECTED)
1393 del_timer(&chan->timer);
1397 string_state = "connected!";
1398 *(u16*)dev->dev_addr = htons(chan->lcn);
1399 netif_wake_queue(dev);
1402 if (chan->protocol == ETH_P_X25)
1403 cycx_x25_chan_send_event(dev, 1);
1406 case WAN_CONNECTING:
1407 string_state = "connecting...";
1409 case WAN_DISCONNECTING:
1410 string_state = "disconnecting...";
1412 case WAN_DISCONNECTED:
1413 string_state = "disconnected!";
1416 *(unsigned short*)dev->dev_addr = 0;
1420 if (chan->protocol == ETH_P_X25)
1421 cycx_x25_chan_send_event(dev, 2);
1423 netif_wake_queue(dev);
1427 printk(KERN_INFO "%s: interface %s %s\n", card->devname,
1428 dev->name, string_state);
1429 chan->state = state;
1432 spin_unlock_irqrestore(&card->lock, flags);
1435 /* Send packet on a logical channel.
1436 * When this function is called, tx_skb field of the channel data space
1437 * points to the transmit socket buffer. When transmission is complete,
1438 * release socket buffer and reset 'tbusy' flag.
1440 * Return: 0 - transmission complete
1444 * 1. If packet length is greater than MTU for this channel, we'll fragment
1445 * the packet into 'complete sequence' using M-bit.
1446 * 2. When transmission is complete, an event notification should be issued
1448 static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
1450 struct cycx_x25_channel *chan = dev->priv;
1451 struct cycx_device *card = chan->card;
1452 int bitm = 0; /* final packet */
1453 unsigned len = skb->len;
1455 if (skb->len > card->wandev.mtu) {
1456 len = card->wandev.mtu;
1457 bitm = 0x10; /* set M-bit (more data) */
1460 if (cycx_x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1468 ++chan->ifstats.tx_packets;
1469 chan->ifstats.tx_bytes += len;
1474 /* Send event (connection, disconnection, etc) to X.25 socket layer */
1476 static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
1478 struct sk_buff *skb;
1481 if ((skb = dev_alloc_skb(1)) == NULL) {
1482 printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
1486 ptr = skb_put(skb, 1);
1490 skb->protocol = htons(ETH_P_X25);
1491 skb->mac.raw = skb->data;
1492 skb->pkt_type = PACKET_HOST;
1495 dev->last_rx = jiffies; /* timestamp */
1498 /* Convert line speed in bps to a number used by cyclom 2x code. */
1499 static u8 bps_to_speed_code(u32 bps)
1501 u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1503 if (bps >= 512000) number = 8;
1504 else if (bps >= 256000) number = 7;
1505 else if (bps >= 64000) number = 6;
1506 else if (bps >= 38400) number = 5;
1507 else if (bps >= 19200) number = 4;
1508 else if (bps >= 9600) number = 3;
1509 else if (bps >= 4800) number = 2;
1510 else if (bps >= 2400) number = 1;
1516 static u8 cycx_log2(u32 n)
1531 /* Convert decimal string to unsigned integer.
1532 * If len != 0 then only 'len' characters of the string are converted. */
1533 static unsigned dec_to_uint(u8 *str, int len)
1540 for (; len && is_digit(*str); ++str, --len)
1541 val = (val * 10) + (*str - (unsigned) '0');
1546 static void reset_timer(struct net_device *dev)
1548 struct cycx_x25_channel *chan = dev->priv;
1551 mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
1553 #ifdef CYCLOMX_X25_DEBUG
1554 static void cycx_x25_dump_config(struct cycx_x25_config *conf)
1556 printk(KERN_INFO "X.25 configuration\n");
1557 printk(KERN_INFO "-----------------\n");
1558 printk(KERN_INFO "link number=%d\n", conf->link);
1559 printk(KERN_INFO "line speed=%d\n", conf->speed);
1560 printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1561 printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1562 printk(KERN_INFO "level 2 window=%d\n", conf->n2win);
1563 printk(KERN_INFO "level 3 window=%d\n", conf->n3win);
1564 printk(KERN_INFO "# logical channels=%d\n", conf->nvc);
1565 printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1566 printk(KERN_INFO "my address=%d\n", conf->locaddr);
1567 printk(KERN_INFO "remote address=%d\n", conf->remaddr);
1568 printk(KERN_INFO "t1=%d seconds\n", conf->t1);
1569 printk(KERN_INFO "t2=%d seconds\n", conf->t2);
1570 printk(KERN_INFO "t21=%d seconds\n", conf->t21);
1571 printk(KERN_INFO "# PVCs=%d\n", conf->npvc);
1572 printk(KERN_INFO "t23=%d seconds\n", conf->t23);
1573 printk(KERN_INFO "flags=0x%x\n", conf->flags);
1576 static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
1578 printk(KERN_INFO "X.25 statistics\n");
1579 printk(KERN_INFO "--------------\n");
1580 printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1581 printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1582 printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1583 printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1584 printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1585 printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1586 printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1587 printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1588 printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1589 printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1592 static void cycx_x25_dump_devs(struct wan_device *wandev)
1594 struct net_device *dev = wandev->dev;
1596 printk(KERN_INFO "X.25 dev states\n");
1597 printk(KERN_INFO "name: addr: txoff: protocol:\n");
1598 printk(KERN_INFO "---------------------------------------\n");
1601 struct cycx_x25_channel *chan = dev->priv;
1603 printk(KERN_INFO "%-5.5s %-15.15s %d ETH_P_%s\n",
1604 chan->name, chan->addr, netif_queue_stopped(dev),
1605 chan->protocol == ETH_P_IP ? "IP" : "X25");
1610 #endif /* CYCLOMX_X25_DEBUG */