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
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,
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
32 * 1999/01/05 acme pktlen now (correctly) uses log2 (value
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 */
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*/
86 struct timer_list timer
; /* timer used for svc channel disc. */
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 */
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)
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...)
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.
177 int cyx_init (cycx_t
*card
, wandev_conf_t
*conf
)
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
);
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
));
200 cfg
.clock
= conf
->clocking
== WANOPT_EXTERNAL
? 8 : 55;
201 cfg
.speed
= bps_to_speed_code(conf
->bps
);
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 */
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;
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 */
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)
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);
260 cfg
.t1
= min(conf
->u
.x25
.t1
, 30);
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);
272 cfg
.n2
= min(conf
->u
.x25
.n2
, 30);
274 /* initialize adapter */
275 if (x25_configure(card
, &cfg
))
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
;
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;
293 /* WAN Device Driver Entry Points */
294 /* Update device status & statistics. */
295 static int update (wan_device_t
*wandev
)
298 if (!wandev
|| !wandev
->private)
301 if (wandev
->state
== WAN_UNCONFIGURED
)
304 x25_get_stats(wandev
->private);
308 /* Create new logical channel.
309 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
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.
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;
324 if (conf
->name
[0] == '\0' || strlen(conf
->name
) > WAN_IFNAME_SZ
) {
325 printk(KERN_INFO
"%s: invalid interface name!\n",card
->devname
);
329 /* allocate and initialize private data */
330 if ((chan
= kmalloc(sizeof(x25_channel_t
), GFP_KERNEL
)) == NULL
)
333 memset(chan
, 0, sizeof(x25_channel_t
));
334 strcpy(chan
->name
, conf
->name
);
336 chan
->link
= conf
->port
;
337 chan
->protocol
= ETH_P_IP
;
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
);
347 if (local_len
> WAN_ADDRESS_SZ
) {
348 printk(KERN_ERR
"%s: %s local addr too long!\n",
349 wandev
->name
, chan
->name
);
352 } else if ((chan
->local_addr
= kmalloc(local_len
+ 1,
353 GFP_KERNEL
)) == NULL
) {
358 strncpy(chan
->local_addr
, conf
->local_addr
,
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
)
377 "%s: PVC %u is out of range on interface %s!\n",
378 wandev
->name
, lcn
, chan
->name
);
382 printk(KERN_ERR
"%s: invalid media address on interface %s!\n",
383 wandev
->name
, chan
->name
);
388 if (chan
->local_addr
)
389 kfree(chan
->local_addr
);
394 /* prepare network device data space for registration */
395 dev
->name
= chan
->name
;
396 dev
->init
= &if_init
;
401 /* Delete logical channel. */
402 static int del_if (wan_device_t
*wandev
, struct device
*dev
)
405 printk(KERN_ERR
"cycx_x25:del_if:dev == NULL!\n");
410 x25_channel_t
*chan
= dev
->priv
;
412 if (chan
->local_addr
)
413 kfree(chan
->local_addr
);
415 if (chan
->state
== WAN_CONNECTED
)
416 del_timer(&chan
->timer
);
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
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 */
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
);
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
;
482 return -EBUSY
; /* only one open is allowed */
484 if (test_and_set_bit(0, (void*)&card
->wandev
.critical
))
492 card
->wandev
.critical
= 0;
496 /* Close network interface.
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
))
509 if (chan
->state
== WAN_CONNECTED
|| chan
->state
== WAN_CONNECTING
)
514 card
->wandev
.critical
= 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
)
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)
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
;
562 ++chan
->ifstats
.rx_dropped
;
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
) {
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
))
587 dev
->trans_start
= jiffies
;
588 if (chan_send(dev
, skb
)) {
594 ++chan
->ifstats
.tx_dropped
;
595 ++card
->wandev
.stats
.tx_dropped
;
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
;
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
);
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
:
638 case X25_ACK_FROM_VC
:
642 log_intr(card
, &cmd
);
645 stat_intr(card
, &cmd
);
647 case X25_CONNECT_CONFIRM
:
648 connect_confirm_intr(card
, &cmd
);
650 case X25_CONNECT_INDICATION
:
651 connect_intr(card
, &cmd
);
653 case X25_DISCONNECT_INDICATION
:
654 disconnect_intr(card
, &cmd
);
656 case X25_DISCONNECT_CONFIRM
:
657 disconnect_confirm_intr(card
, &cmd
);
660 cyclomx_set_state(card
, WAN_CONNECTED
);
663 cyclomx_set_state(card
, WAN_DISCONNECTED
);
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
);
679 card
->wandev
.critical
= 0;
680 spin_unlock_irqrestore(&card
->lock
, host_cpu_flags
);
682 if (card
->buff_int_mode_unbusy
)
686 /* Transmit interrupt handler.
687 * o Release socket buffer
688 * o Clear 'tbusy' flag */
689 static void tx_intr (cycx_t
*card
, TX25Cmd
*cmd
)
692 wan_device_t
*wandev
= &card
->wandev
;
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;
702 printk(KERN_ERR
"%s:ackvc for inexistent lcn %d\n",
706 /* Receive interrupt handler.
707 * This routine handles fragmented IP packets using M-bit according to the
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.
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
;
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
));
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",
743 if (chan
->drop_sequence
)
745 chan
->drop_sequence
= 0;
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",
757 chan
->drop_sequence
= 1;
758 ++chan
->ifstats
.rx_dropped
;
763 skb
->protocol
= htons(chan
->protocol
);
767 if (skb_tailroom(skb
) < pktlen
) {
768 /* No room for the packet. Call off the whole thing! */
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
;
781 /* Append packet to the socket buffer */
782 cycx_peek(&card
->hw
, cmd
->buf
+ 5, skb_put(skb
, pktlen
), pktlen
);
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
);
792 skb
->mac
.raw
= skb
->data
;
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
;
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;
816 local
[0] = rem
[0] = '\0';
819 nibble_to_byte(data
, local
, sizelocal
, 0);
822 nibble_to_byte(data
+ (sizelocal
>> 1), rem
, sizerem
, sizelocal
& 1);
823 dprintk(KERN_INFO
"connect_intr:lcn=%d, local=%s, remote=%s\n",
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",
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
;
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
);
858 clear_bit(--key
, (void*)&card
->u
.x
.connection_keys
);
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
;
871 cycx_peek(&card
->hw
, cmd
->buf
, &lcn
, sizeof(lcn
));
872 dprintk(KERN_INFO
"%s: disconnect_confirm_intr:lcn=%d\n",
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",
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
;
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
904 u16 size
, toread
, link
, msg_code
;
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
);
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.
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],
952 if (len
>= (sizeof(hex
) / 2))
953 len
= (sizeof(hex
) / 2) - 1;
956 sprintf(phex
, "%02x", *p
++);
960 printk(KERN_INFO
"%s: %s\n", msg
, hex
);
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
)
978 u32 addr
= 0x1200 + 0x2E0 * link
+ 0x1E2;
985 if (test_and_set_bit(0, (void*)&card
->u
.x
.critical
))
989 cycx_poke(&card
->hw
, X25_MBOX_OFFS
, &c
, sizeof(c
) - sizeof(c
.buf
));
993 cycx_poke(&card
->hw
, addr
, data1
, len1
);
997 u32 addr1
= 0xA00 + 0x400 * link
;
999 cycx_poke(&card
->hw
, addr
+ len1
, data2
, 249);
1000 cycx_poke(&card
->hw
, addr1
, ((u8
*) data2
) + 249,
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;
1016 /* Configure adapter. */
1017 static int x25_configure (cycx_t
*card
, TX25Config
*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!!!
1050 int err
= x25_exec(card
, X25_STATISTIC
, 0, NULL
, 20, NULL
, 0);
1055 interruptible_sleep_on(&card
->wait_stats
);
1057 if (signal_pending(current
))
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
);
1078 /* return the number of nibbles */
1079 static int byte_to_nibble(u8
*s
, u8
*d
, char *nibble
)
1083 if (*nibble
&& *s
) {
1090 d
[i
] = (*s
- '0') << 4;
1092 d
[i
] |= *(s
+ 1) - '0';
1104 static void nibble_to_byte(u8
*s
, u8
*d
, u8 len
, u8 nibble
)
1107 *d
++ = '0' + (*s
++ & 0x0F);
1112 *d
++ = '0' + (*s
>> 4);
1114 *d
++ = '0' + (*s
& 0x0F);
1124 /* Place X.25 call. */
1125 static int x25_place_call (cycx_t
*card
, x25_channel_t
*chan
)
1128 retry
= MAX_CMD_RETRY
,
1132 mylen
= chan
->local_addr
? strlen(chan
->local_addr
) : 0,
1133 remotelen
= strlen(chan
->addr
);
1136 if (card
->u
.x
.connection_keys
== ~0UL) {
1137 printk(KERN_INFO
"%s: too many simultaneous connection "
1138 "requests!\n", card
->devname
);
1142 key
= ffz(card
->u
.x
.connection_keys
);
1143 set_bit(key
, (void*)&card
->u
.x
.connection_keys
);
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 */
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;
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
--);
1164 clear_bit(--key
, (void*)&card
->u
.x
.connection_keys
);
1167 chan
->protocol
= ETH_P_IP
;
1173 /* Place X.25 CONNECT RESPONSE. */
1174 static int x25_connect_response (cycx_t
*card
, x25_channel_t
*chan
)
1177 retry
= MAX_CMD_RETRY
;
1180 memset(data
, 0, sizeof(data
));
1181 data
[0] = data
[3] = chan
->lcn
;
1184 data
[7] = 0xCC; /* TCP/IP over X.25, thanx Daniela */
1186 do err
= x25_exec(card
, X25_CONNECT_RESPONSE
, chan
->link
,
1188 while (err
&& retry
--);
1193 /* Place X.25 DISCONNECT RESPONSE. */
1194 static int x25_disconnect_response (cycx_t
*card
, u8 link
, u8 lcn
)
1197 retry
= MAX_CMD_RETRY
;
1200 memset(data
, 0, sizeof(data
));
1201 data
[0] = data
[3] = lcn
;
1204 do err
= x25_exec(card
, X25_DISCONNECT_RESPONSE
, link
,
1206 while (err
&& retry
--);
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
,
1218 memset(data
, 0, sizeof(data
));
1219 data
[0] = data
[3] = lcn
;
1225 do err
= x25_exec(card
, X25_DISCONNECT_REQUEST
, link
, data
, 7, NULL
, 0);
1226 while (err
&& retry
--);
1231 /* Send X.25 data packet. */
1232 static int x25_send (cycx_t
*card
, u8 link
, u8 lcn
, u8 bitm
, int len
, void *buf
)
1235 retry
= MAX_CMD_RETRY
;
1236 u8 data
[] = "?\xFF\x10??";
1238 data
[0] = data
[3] = lcn
;
1241 do err
= x25_exec(card
, X25_DATA_REQUEST
, link
, &data
, 5, buf
, len
);
1242 while (err
&& retry
--);
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
)
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
))
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
1277 static int chan_connect (struct device
*dev
)
1279 x25_channel_t
*chan
= dev
->priv
;
1280 cycx_t
*card
= chan
->card
;
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
))
1289 set_chan_state(dev
, WAN_CONNECTING
, OUT_INTR
);
1292 set_chan_state(dev
, WAN_CONNECTED
, OUT_INTR
);
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
;
1304 x25_clear_call(chan
->card
, chan
->link
, chan
->lcn
, 0, 0);
1305 set_chan_state(dev
, WAN_DISCONNECTING
, OUT_INTR
);
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
) {
1321 printk (KERN_ERR
"%s: chan_timer for svc (%s) not "
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
;
1335 spin_lock(&card
->lock
);
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
);
1345 printk (KERN_INFO
"%s: interface %s "
1347 card
->devname
, dev
->name
);
1348 *(u16
*)dev
->dev_addr
= htons(chan
->lcn
);
1353 case WAN_CONNECTING
:
1354 printk (KERN_INFO
"%s: interface %s "
1356 card
->devname
, dev
->name
);
1359 case WAN_DISCONNECTING
:
1360 printk (KERN_INFO
"%s: interface %s "
1361 "disconnecting...\n",
1362 card
->devname
, dev
->name
);
1365 case WAN_DISCONNECTED
:
1366 printk (KERN_INFO
"%s: interface %s "
1368 card
->devname
, dev
->name
);
1370 *(unsigned short*)dev
->dev_addr
= 0;
1376 chan
->state
= state
;
1380 spin_unlock(&card
->lock
);
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
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
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
))
1418 ++chan
->ifstats
.tx_packets
;
1419 chan
->ifstats
.tx_bytes
+= len
;
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;
1441 static u8
log2 (u32 n
)
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
)
1465 for (; len
&& is_digit(*str
); ++str
, --len
)
1466 val
= (val
* 10) + (*str
- (unsigned)'0');
1471 static void reset_timer(struct device
*dev
)
1473 x25_channel_t
*chan
= dev
->priv
;
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 */