Merge branch 'mini2440-dev-unlikely' into mini2440-dev
[linux-2.6/mini2440.git] / drivers / net / wan / cycx_x25.c
blobcd8cb95c5bd78920c648b2b47831bd9e086bb701
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-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
23 * firmware onboard
24 * 1999/10/18 acme support for X.25 sockets in if_send,
25 * beware: socket(AF_X25...) IS WORK IN PROGRESS,
26 * TCP/IP over X.25 via wanrouter not affected,
27 * working.
28 * 1999/10/09 acme chan_disc renamed to chan_disconnect,
29 * began adding support for X.25 sockets:
30 * conf->protocol in new_if
31 * 1999/10/05 acme fixed return E... to return -E...
32 * 1999/08/10 acme serialized access to the card thru a spinlock
33 * in x25_exec
34 * 1999/08/09 acme removed per channel spinlocks
35 * removed references to enable_tx_int
36 * 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated
37 * if_send simplified
38 * 1999/05/25 acme fixed t1, t2, t21 & t23 configuration
39 * use spinlocks instead of cli/sti in some points
40 * 1999/05/24 acme finished the x25_get_stat function
41 * 1999/05/23 acme dev->type = ARPHRD_X25 (tcpdump only works,
42 * AFAIT, with ARPHRD_ETHER). This seems to be
43 * needed to use socket(AF_X25)...
44 * Now the config file must specify a peer media
45 * address for svc channels over a crossover cable.
46 * Removed hold_timeout from x25_channel_t,
47 * not used.
48 * A little enhancement in the DEBUG processing
49 * 1999/05/22 acme go to DISCONNECTED in disconnect_confirm_intr,
50 * instead of chan_disc.
51 * 1999/05/16 marcelo fixed timer initialization in SVCs
52 * 1999/01/05 acme x25_configure now get (most of) all
53 * parameters...
54 * 1999/01/05 acme pktlen now (correctly) uses log2 (value
55 * configured)
56 * 1999/01/03 acme judicious use of data types (u8, u16, u32, etc)
57 * 1999/01/03 acme cyx_isr: reset dpmbase to acknowledge
58 * indication (interrupt from cyclom 2x)
59 * 1999/01/02 acme cyx_isr: first hackings...
60 * 1999/01/0203 acme when initializing an array don't give less
61 * elements than declared...
62 * example: char send_cmd[6] = "?\xFF\x10";
63 * you'll gonna lose a couple hours, 'cause your
64 * brain won't admit that there's an error in the
65 * above declaration... the side effect is that
66 * memset is put into the unresolved symbols
67 * instead of using the inline memset functions...
68 * 1999/01/02 acme began chan_connect, chan_send, x25_send
69 * 1998/12/31 acme x25_configure
70 * this code can be compiled as non module
71 * 1998/12/27 acme code cleanup
72 * IPX code wiped out! let's decrease code
73 * complexity for now, remember: I'm learning! :)
74 * bps_to_speed_code OK
75 * 1998/12/26 acme Minimal debug code cleanup
76 * 1998/08/08 acme Initial version.
79 #define CYCLOMX_X25_DEBUG 1
81 #include <linux/ctype.h> /* isdigit() */
82 #include <linux/errno.h> /* return codes */
83 #include <linux/if_arp.h> /* ARPHRD_HWX25 */
84 #include <linux/kernel.h> /* printk(), and other useful stuff */
85 #include <linux/module.h>
86 #include <linux/string.h> /* inline memset(), etc. */
87 #include <linux/sched.h>
88 #include <linux/slab.h> /* kmalloc(), kfree() */
89 #include <linux/stddef.h> /* offsetof(), etc. */
90 #include <linux/wanrouter.h> /* WAN router definitions */
92 #include <asm/byteorder.h> /* htons(), etc. */
94 #include <linux/cyclomx.h> /* Cyclom 2X common user API definitions */
95 #include <linux/cycx_x25.h> /* X.25 firmware API definitions */
97 #include <net/x25device.h>
99 /* Defines & Macros */
100 #define CYCX_X25_MAX_CMD_RETRY 5
101 #define CYCX_X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
103 /* Data Structures */
104 /* This is an extension of the 'struct net_device' we create for each network
105 interface to keep the rest of X.25 channel-specific data. */
106 struct cycx_x25_channel {
107 /* This member must be first. */
108 struct net_device *slave; /* WAN slave */
110 char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
111 char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
112 char *local_addr; /* local media address, ASCIIZ -
113 svc thru crossover cable */
114 s16 lcn; /* logical channel number/conn.req.key*/
115 u8 link;
116 struct timer_list timer; /* timer used for svc channel disc. */
117 u16 protocol; /* ethertype, 0 - multiplexed */
118 u8 svc; /* 0 - permanent, 1 - switched */
119 u8 state; /* channel state */
120 u8 drop_sequence; /* mark sequence for dropping */
121 u32 idle_tmout; /* sec, before disconnecting */
122 struct sk_buff *rx_skb; /* receive socket buffer */
123 struct cycx_device *card; /* -> owner */
124 struct net_device_stats ifstats;/* interface statistics */
127 /* Function Prototypes */
128 /* WAN link driver entry points. These are called by the WAN router module. */
129 static int cycx_wan_update(struct wan_device *wandev),
130 cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
131 wanif_conf_t *conf),
132 cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
134 /* Network device interface */
135 static int cycx_netdevice_init(struct net_device *dev);
136 static int cycx_netdevice_open(struct net_device *dev);
137 static int cycx_netdevice_stop(struct net_device *dev);
138 static int cycx_netdevice_hard_header(struct sk_buff *skb,
139 struct net_device *dev, u16 type,
140 const void *daddr, const void *saddr,
141 unsigned len);
142 static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
143 static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
144 struct net_device *dev);
146 static struct net_device_stats *
147 cycx_netdevice_get_stats(struct net_device *dev);
149 /* Interrupt handlers */
150 static void cycx_x25_irq_handler(struct cycx_device *card),
151 cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
152 cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
153 cycx_x25_irq_log(struct cycx_device *card,
154 struct cycx_x25_cmd *cmd),
155 cycx_x25_irq_stat(struct cycx_device *card,
156 struct cycx_x25_cmd *cmd),
157 cycx_x25_irq_connect_confirm(struct cycx_device *card,
158 struct cycx_x25_cmd *cmd),
159 cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
160 struct cycx_x25_cmd *cmd),
161 cycx_x25_irq_connect(struct cycx_device *card,
162 struct cycx_x25_cmd *cmd),
163 cycx_x25_irq_disconnect(struct cycx_device *card,
164 struct cycx_x25_cmd *cmd),
165 cycx_x25_irq_spurious(struct cycx_device *card,
166 struct cycx_x25_cmd *cmd);
168 /* X.25 firmware interface functions */
169 static int cycx_x25_configure(struct cycx_device *card,
170 struct cycx_x25_config *conf),
171 cycx_x25_get_stats(struct cycx_device *card),
172 cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
173 int len, void *buf),
174 cycx_x25_connect_response(struct cycx_device *card,
175 struct cycx_x25_channel *chan),
176 cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
177 u8 lcn);
179 /* channel functions */
180 static int cycx_x25_chan_connect(struct net_device *dev),
181 cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb);
183 static void cycx_x25_chan_disconnect(struct net_device *dev),
184 cycx_x25_chan_send_event(struct net_device *dev, u8 event);
186 /* Miscellaneous functions */
187 static void cycx_x25_set_chan_state(struct net_device *dev, u8 state),
188 cycx_x25_chan_timer(unsigned long d);
190 static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble),
191 reset_timer(struct net_device *dev);
193 static u8 bps_to_speed_code(u32 bps);
194 static u8 cycx_log2(u32 n);
196 static unsigned dec_to_uint(u8 *str, int len);
198 static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
199 s16 lcn);
200 static struct net_device *
201 cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
203 static void cycx_x25_chan_setup(struct net_device *dev);
205 #ifdef CYCLOMX_X25_DEBUG
206 static void hex_dump(char *msg, unsigned char *p, int len);
207 static void cycx_x25_dump_config(struct cycx_x25_config *conf);
208 static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
209 static void cycx_x25_dump_devs(struct wan_device *wandev);
210 #else
211 #define hex_dump(msg, p, len)
212 #define cycx_x25_dump_config(conf)
213 #define cycx_x25_dump_stats(stats)
214 #define cycx_x25_dump_devs(wandev)
215 #endif
216 /* Public Functions */
218 /* X.25 Protocol Initialization routine.
220 * This routine is called by the main Cyclom 2X module during setup. At this
221 * point adapter is completely initialized and X.25 firmware is running.
222 * o configure adapter
223 * o initialize protocol-specific fields of the adapter data space.
225 * Return: 0 o.k.
226 * < 0 failure. */
227 int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
229 struct cycx_x25_config cfg;
231 /* Verify configuration ID */
232 if (conf->config_id != WANCONFIG_X25) {
233 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
234 card->devname, conf->config_id);
235 return -EINVAL;
238 /* Initialize protocol-specific fields */
239 card->mbox = card->hw.dpmbase + X25_MBOX_OFFS;
240 card->u.x.connection_keys = 0;
241 spin_lock_init(&card->u.x.lock);
243 /* Configure adapter. Here we set reasonable defaults, then parse
244 * device configuration structure and set configuration options.
245 * Most configuration options are verified and corrected (if
246 * necessary) since we can't rely on the adapter to do so and don't
247 * want it to fail either. */
248 memset(&cfg, 0, sizeof(cfg));
249 cfg.link = 0;
250 cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
251 cfg.speed = bps_to_speed_code(conf->bps);
252 cfg.n3win = 7;
253 cfg.n2win = 2;
254 cfg.n2 = 5;
255 cfg.nvc = 1;
256 cfg.npvc = 1;
257 cfg.flags = 0x02; /* default = V35 */
258 cfg.t1 = 10; /* line carrier timeout */
259 cfg.t2 = 29; /* tx timeout */
260 cfg.t21 = 180; /* CALL timeout */
261 cfg.t23 = 180; /* CLEAR timeout */
263 /* adjust MTU */
264 if (!conf->mtu || conf->mtu >= 512)
265 card->wandev.mtu = 512;
266 else if (conf->mtu >= 256)
267 card->wandev.mtu = 256;
268 else if (conf->mtu >= 128)
269 card->wandev.mtu = 128;
270 else
271 card->wandev.mtu = 64;
273 cfg.pktlen = cycx_log2(card->wandev.mtu);
275 if (conf->station == WANOPT_DTE) {
276 cfg.locaddr = 3; /* DTE */
277 cfg.remaddr = 1; /* DCE */
278 } else {
279 cfg.locaddr = 1; /* DCE */
280 cfg.remaddr = 3; /* DTE */
283 if (conf->interface == WANOPT_RS232)
284 cfg.flags = 0; /* FIXME just reset the 2nd bit */
286 if (conf->u.x25.hi_pvc) {
287 card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
288 card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
291 if (conf->u.x25.hi_svc) {
292 card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
293 card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
296 if (card->u.x.lo_pvc == 255)
297 cfg.npvc = 0;
298 else
299 cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
301 cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
303 if (conf->u.x25.hdlc_window)
304 cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
306 if (conf->u.x25.pkt_window)
307 cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
309 if (conf->u.x25.t1)
310 cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
312 if (conf->u.x25.t2)
313 cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
315 if (conf->u.x25.t11_t21)
316 cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
318 if (conf->u.x25.t13_t23)
319 cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
321 if (conf->u.x25.n2)
322 cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
324 /* initialize adapter */
325 if (cycx_x25_configure(card, &cfg))
326 return -EIO;
328 /* Initialize protocol-specific fields of adapter data space */
329 card->wandev.bps = conf->bps;
330 card->wandev.interface = conf->interface;
331 card->wandev.clocking = conf->clocking;
332 card->wandev.station = conf->station;
333 card->isr = cycx_x25_irq_handler;
334 card->exec = NULL;
335 card->wandev.update = cycx_wan_update;
336 card->wandev.new_if = cycx_wan_new_if;
337 card->wandev.del_if = cycx_wan_del_if;
338 card->wandev.state = WAN_DISCONNECTED;
340 return 0;
343 /* WAN Device Driver Entry Points */
344 /* Update device status & statistics. */
345 static int cycx_wan_update(struct wan_device *wandev)
347 /* sanity checks */
348 if (!wandev || !wandev->private)
349 return -EFAULT;
351 if (wandev->state == WAN_UNCONFIGURED)
352 return -ENODEV;
354 cycx_x25_get_stats(wandev->private);
356 return 0;
359 /* Create new logical channel.
360 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
361 * handled.
362 * o parse media- and hardware-specific configuration
363 * o make sure that a new channel can be created
364 * o allocate resources, if necessary
365 * o prepare network device structure for registration.
367 * Return: 0 o.k.
368 * < 0 failure (channel will not be created) */
369 static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
370 wanif_conf_t *conf)
372 struct cycx_device *card = wandev->private;
373 struct cycx_x25_channel *chan;
374 int err = 0;
376 if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
377 printk(KERN_INFO "%s: invalid interface name!\n",
378 card->devname);
379 return -EINVAL;
382 dev = alloc_netdev(sizeof(struct cycx_x25_channel), conf->name,
383 cycx_x25_chan_setup);
384 if (!dev)
385 return -ENOMEM;
387 chan = netdev_priv(dev);
388 strcpy(chan->name, conf->name);
389 chan->card = card;
390 chan->link = conf->port;
391 chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
392 chan->rx_skb = NULL;
393 /* only used in svc connected thru crossover cable */
394 chan->local_addr = NULL;
396 if (conf->addr[0] == '@') { /* SVC */
397 int len = strlen(conf->local_addr);
399 if (len) {
400 if (len > WAN_ADDRESS_SZ) {
401 printk(KERN_ERR "%s: %s local addr too long!\n",
402 wandev->name, chan->name);
403 err = -EINVAL;
404 goto error;
405 } else {
406 chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
408 if (!chan->local_addr) {
409 err = -ENOMEM;
410 goto error;
414 strncpy(chan->local_addr, conf->local_addr,
415 WAN_ADDRESS_SZ);
418 chan->svc = 1;
419 strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
420 init_timer(&chan->timer);
421 chan->timer.function = cycx_x25_chan_timer;
422 chan->timer.data = (unsigned long)dev;
424 /* Set channel timeouts (default if not specified) */
425 chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
426 } else if (isdigit(conf->addr[0])) { /* PVC */
427 s16 lcn = dec_to_uint(conf->addr, 0);
429 if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
430 chan->lcn = lcn;
431 else {
432 printk(KERN_ERR
433 "%s: PVC %u is out of range on interface %s!\n",
434 wandev->name, lcn, chan->name);
435 err = -EINVAL;
436 goto error;
438 } else {
439 printk(KERN_ERR "%s: invalid media address on interface %s!\n",
440 wandev->name, chan->name);
441 err = -EINVAL;
442 goto error;
445 return 0;
447 error:
448 free_netdev(dev);
449 return err;
452 /* Delete logical channel. */
453 static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
455 struct cycx_x25_channel *chan = netdev_priv(dev);
457 if (chan->svc) {
458 kfree(chan->local_addr);
459 if (chan->state == WAN_CONNECTED)
460 del_timer(&chan->timer);
463 return 0;
467 /* Network Device Interface */
469 static const struct header_ops cycx_header_ops = {
470 .create = cycx_netdevice_hard_header,
471 .rebuild = cycx_netdevice_rebuild_header,
474 static const struct net_device_ops cycx_netdev_ops = {
475 .ndo_init = cycx_netdevice_init,
476 .ndo_open = cycx_netdevice_open,
477 .ndo_stop = cycx_netdevice_stop,
478 .ndo_start_xmit = cycx_netdevice_hard_start_xmit,
479 .ndo_get_stats = cycx_netdevice_get_stats,
482 static void cycx_x25_chan_setup(struct net_device *dev)
484 /* Initialize device driver entry points */
485 dev->netdev_ops = &cycx_netdev_ops;
486 dev->header_ops = &cycx_header_ops;
488 /* Initialize media-specific parameters */
489 dev->mtu = CYCX_X25_CHAN_MTU;
490 dev->type = ARPHRD_HWX25; /* ARP h/w type */
491 dev->hard_header_len = 0; /* media header length */
492 dev->addr_len = 0; /* hardware address length */
495 /* Initialize Linux network interface.
497 * This routine is called only once for each interface, during Linux network
498 * interface registration. Returning anything but zero will fail interface
499 * registration. */
500 static int cycx_netdevice_init(struct net_device *dev)
502 struct cycx_x25_channel *chan = netdev_priv(dev);
503 struct cycx_device *card = chan->card;
504 struct wan_device *wandev = &card->wandev;
506 if (!chan->svc)
507 *(__be16*)dev->dev_addr = htons(chan->lcn);
509 /* Initialize hardware parameters (just for reference) */
510 dev->irq = wandev->irq;
511 dev->dma = wandev->dma;
512 dev->base_addr = wandev->ioport;
513 dev->mem_start = (unsigned long)wandev->maddr;
514 dev->mem_end = (unsigned long)(wandev->maddr +
515 wandev->msize - 1);
516 dev->flags |= IFF_NOARP;
518 /* Set transmit buffer queue length */
519 dev->tx_queue_len = 10;
521 /* Initialize socket buffers */
522 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
524 return 0;
527 /* Open network interface.
528 * o prevent module from unloading by incrementing use count
529 * o if link is disconnected then initiate connection
531 * Return 0 if O.k. or errno. */
532 static int cycx_netdevice_open(struct net_device *dev)
534 if (netif_running(dev))
535 return -EBUSY; /* only one open is allowed */
537 netif_start_queue(dev);
538 return 0;
541 /* Close network interface.
542 * o reset flags.
543 * o if there's no more open channels then disconnect physical link. */
544 static int cycx_netdevice_stop(struct net_device *dev)
546 struct cycx_x25_channel *chan = netdev_priv(dev);
548 netif_stop_queue(dev);
550 if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
551 cycx_x25_chan_disconnect(dev);
553 return 0;
556 /* Build media header.
557 * o encapsulate packet according to encapsulation type.
559 * The trick here is to put packet type (Ethertype) into 'protocol' field of
560 * the socket buffer, so that we don't forget it. If encapsulation fails,
561 * set skb->protocol to 0 and discard packet later.
563 * Return: media header length. */
564 static int cycx_netdevice_hard_header(struct sk_buff *skb,
565 struct net_device *dev, u16 type,
566 const void *daddr, const void *saddr,
567 unsigned len)
569 skb->protocol = htons(type);
571 return dev->hard_header_len;
574 /* * Re-build media header.
575 * Return: 1 physical address resolved.
576 * 0 physical address not resolved */
577 static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
579 return 1;
582 /* Send a packet on a network interface.
583 * o set busy flag (marks start of the transmission).
584 * o check link state. If link is not up, then drop the packet.
585 * o check channel status. If it's down then initiate a call.
586 * o pass a packet to corresponding WAN device.
587 * o free socket buffer
589 * Return: 0 complete (socket buffer must be freed)
590 * non-0 packet may be re-transmitted (tbusy must be set)
592 * Notes:
593 * 1. This routine is called either by the protocol stack or by the "net
594 * bottom half" (with interrupts enabled).
595 * 2. Setting tbusy flag will inhibit further transmit requests from the
596 * protocol stack and can be used for flow control with protocol layer. */
597 static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
598 struct net_device *dev)
600 struct cycx_x25_channel *chan = netdev_priv(dev);
601 struct cycx_device *card = chan->card;
603 if (!chan->svc)
604 chan->protocol = ntohs(skb->protocol);
606 if (card->wandev.state != WAN_CONNECTED)
607 ++chan->ifstats.tx_dropped;
608 else if (chan->svc && chan->protocol &&
609 chan->protocol != ntohs(skb->protocol)) {
610 printk(KERN_INFO
611 "%s: unsupported Ethertype 0x%04X on interface %s!\n",
612 card->devname, ntohs(skb->protocol), dev->name);
613 ++chan->ifstats.tx_errors;
614 } else if (chan->protocol == ETH_P_IP) {
615 switch (chan->state) {
616 case WAN_DISCONNECTED:
617 if (cycx_x25_chan_connect(dev)) {
618 netif_stop_queue(dev);
619 return NETDEV_TX_BUSY;
621 /* fall thru */
622 case WAN_CONNECTED:
623 reset_timer(dev);
624 dev->trans_start = jiffies;
625 netif_stop_queue(dev);
627 if (cycx_x25_chan_send(dev, skb))
628 return NETDEV_TX_BUSY;
630 break;
631 default:
632 ++chan->ifstats.tx_dropped;
633 ++card->wandev.stats.tx_dropped;
635 } else { /* chan->protocol == ETH_P_X25 */
636 switch (skb->data[0]) {
637 case 0: break;
638 case 1: /* Connect request */
639 cycx_x25_chan_connect(dev);
640 goto free_packet;
641 case 2: /* Disconnect request */
642 cycx_x25_chan_disconnect(dev);
643 goto free_packet;
644 default:
645 printk(KERN_INFO
646 "%s: unknown %d x25-iface request on %s!\n",
647 card->devname, skb->data[0], dev->name);
648 ++chan->ifstats.tx_errors;
649 goto free_packet;
652 skb_pull(skb, 1); /* Remove control byte */
653 reset_timer(dev);
654 dev->trans_start = jiffies;
655 netif_stop_queue(dev);
657 if (cycx_x25_chan_send(dev, skb)) {
658 /* prepare for future retransmissions */
659 skb_push(skb, 1);
660 return NETDEV_TX_BUSY;
664 free_packet:
665 dev_kfree_skb(skb);
667 return NETDEV_TX_OK;
670 /* Get Ethernet-style interface statistics.
671 * Return a pointer to struct net_device_stats */
672 static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
674 struct cycx_x25_channel *chan = netdev_priv(dev);
676 return chan ? &chan->ifstats : NULL;
679 /* Interrupt Handlers */
680 /* X.25 Interrupt Service Routine. */
681 static void cycx_x25_irq_handler(struct cycx_device *card)
683 struct cycx_x25_cmd cmd;
684 u16 z = 0;
686 card->in_isr = 1;
687 card->buff_int_mode_unbusy = 0;
688 cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
690 switch (cmd.command) {
691 case X25_DATA_INDICATION:
692 cycx_x25_irq_rx(card, &cmd);
693 break;
694 case X25_ACK_FROM_VC:
695 cycx_x25_irq_tx(card, &cmd);
696 break;
697 case X25_LOG:
698 cycx_x25_irq_log(card, &cmd);
699 break;
700 case X25_STATISTIC:
701 cycx_x25_irq_stat(card, &cmd);
702 break;
703 case X25_CONNECT_CONFIRM:
704 cycx_x25_irq_connect_confirm(card, &cmd);
705 break;
706 case X25_CONNECT_INDICATION:
707 cycx_x25_irq_connect(card, &cmd);
708 break;
709 case X25_DISCONNECT_INDICATION:
710 cycx_x25_irq_disconnect(card, &cmd);
711 break;
712 case X25_DISCONNECT_CONFIRM:
713 cycx_x25_irq_disconnect_confirm(card, &cmd);
714 break;
715 case X25_LINE_ON:
716 cycx_set_state(card, WAN_CONNECTED);
717 break;
718 case X25_LINE_OFF:
719 cycx_set_state(card, WAN_DISCONNECTED);
720 break;
721 default:
722 cycx_x25_irq_spurious(card, &cmd);
723 break;
726 cycx_poke(&card->hw, 0, &z, sizeof(z));
727 cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
728 card->in_isr = 0;
731 /* Transmit interrupt handler.
732 * o Release socket buffer
733 * o Clear 'tbusy' flag */
734 static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
736 struct net_device *dev;
737 struct wan_device *wandev = &card->wandev;
738 u8 lcn;
740 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
742 /* unbusy device and then dev_tint(); */
743 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
744 if (dev) {
745 card->buff_int_mode_unbusy = 1;
746 netif_wake_queue(dev);
747 } else
748 printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n",
749 card->devname, lcn);
752 /* Receive interrupt handler.
753 * This routine handles fragmented IP packets using M-bit according to the
754 * RFC1356.
755 * o map logical channel number to network interface.
756 * o allocate socket buffer or append received packet to the existing one.
757 * o if M-bit is reset (i.e. it's the last packet in a sequence) then
758 * decapsulate packet and pass socket buffer to the protocol stack.
760 * Notes:
761 * 1. When allocating a socket buffer, if M-bit is set then more data is
762 * coming and we have to allocate buffer for the maximum IP packet size
763 * expected on this channel.
764 * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
765 * socket buffers available) the whole packet sequence must be discarded. */
766 static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
768 struct wan_device *wandev = &card->wandev;
769 struct net_device *dev;
770 struct cycx_x25_channel *chan;
771 struct sk_buff *skb;
772 u8 bitm, lcn;
773 int pktlen = cmd->len - 5;
775 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
776 cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
777 bitm &= 0x10;
779 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
780 if (!dev) {
781 /* Invalid channel, discard packet */
782 printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
783 card->devname, lcn);
784 return;
787 chan = netdev_priv(dev);
788 reset_timer(dev);
790 if (chan->drop_sequence) {
791 if (!bitm)
792 chan->drop_sequence = 0;
793 else
794 return;
797 if ((skb = chan->rx_skb) == NULL) {
798 /* Allocate new socket buffer */
799 int bufsize = bitm ? dev->mtu : pktlen;
801 if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
802 bufsize +
803 dev->hard_header_len)) == NULL) {
804 printk(KERN_INFO "%s: no socket buffers available!\n",
805 card->devname);
806 chan->drop_sequence = 1;
807 ++chan->ifstats.rx_dropped;
808 return;
811 if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
812 /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
813 skb_put(skb, 1);
815 skb->dev = dev;
816 skb->protocol = htons(chan->protocol);
817 chan->rx_skb = skb;
820 if (skb_tailroom(skb) < pktlen) {
821 /* No room for the packet. Call off the whole thing! */
822 dev_kfree_skb_irq(skb);
823 chan->rx_skb = NULL;
825 if (bitm)
826 chan->drop_sequence = 1;
828 printk(KERN_INFO "%s: unexpectedly long packet sequence "
829 "on interface %s!\n", card->devname, dev->name);
830 ++chan->ifstats.rx_length_errors;
831 return;
834 /* Append packet to the socket buffer */
835 cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
837 if (bitm)
838 return; /* more data is coming */
840 chan->rx_skb = NULL; /* dequeue packet */
842 ++chan->ifstats.rx_packets;
843 chan->ifstats.rx_bytes += pktlen;
845 skb_reset_mac_header(skb);
846 netif_rx(skb);
849 /* Connect interrupt handler. */
850 static void cycx_x25_irq_connect(struct cycx_device *card,
851 struct cycx_x25_cmd *cmd)
853 struct wan_device *wandev = &card->wandev;
854 struct net_device *dev = NULL;
855 struct cycx_x25_channel *chan;
856 u8 d[32],
857 loc[24],
858 rem[24];
859 u8 lcn, sizeloc, sizerem;
861 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
862 cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
863 cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
865 sizerem = sizeloc >> 4;
866 sizeloc &= 0x0F;
868 loc[0] = rem[0] = '\0';
870 if (sizeloc)
871 nibble_to_byte(d, loc, sizeloc, 0);
873 if (sizerem)
874 nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
876 dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
877 __func__, lcn, loc, rem);
879 dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
880 if (!dev) {
881 /* Invalid channel, discard packet */
882 printk(KERN_INFO "%s: connect not expected: remote %s!\n",
883 card->devname, rem);
884 return;
887 chan = netdev_priv(dev);
888 chan->lcn = lcn;
889 cycx_x25_connect_response(card, chan);
890 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
893 /* Connect confirm interrupt handler. */
894 static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
895 struct cycx_x25_cmd *cmd)
897 struct wan_device *wandev = &card->wandev;
898 struct net_device *dev;
899 struct cycx_x25_channel *chan;
900 u8 lcn, key;
902 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
903 cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
904 dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
905 card->devname, __func__, lcn, key);
907 dev = cycx_x25_get_dev_by_lcn(wandev, -key);
908 if (!dev) {
909 /* Invalid channel, discard packet */
910 clear_bit(--key, (void*)&card->u.x.connection_keys);
911 printk(KERN_INFO "%s: connect confirm not expected: lcn %d, "
912 "key=%d!\n", card->devname, lcn, key);
913 return;
916 clear_bit(--key, (void*)&card->u.x.connection_keys);
917 chan = netdev_priv(dev);
918 chan->lcn = lcn;
919 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
922 /* Disconnect confirm interrupt handler. */
923 static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
924 struct cycx_x25_cmd *cmd)
926 struct wan_device *wandev = &card->wandev;
927 struct net_device *dev;
928 u8 lcn;
930 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
931 dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
932 card->devname, __func__, lcn);
933 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
934 if (!dev) {
935 /* Invalid channel, discard packet */
936 printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n",
937 card->devname, lcn);
938 return;
941 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
944 /* disconnect interrupt handler. */
945 static void cycx_x25_irq_disconnect(struct cycx_device *card,
946 struct cycx_x25_cmd *cmd)
948 struct wan_device *wandev = &card->wandev;
949 struct net_device *dev;
950 u8 lcn;
952 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
953 dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn);
955 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
956 if (dev) {
957 struct cycx_x25_channel *chan = netdev_priv(dev);
959 cycx_x25_disconnect_response(card, chan->link, lcn);
960 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
961 } else
962 cycx_x25_disconnect_response(card, 0, lcn);
965 /* LOG interrupt handler. */
966 static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd)
968 #if CYCLOMX_X25_DEBUG
969 char bf[20];
970 u16 size, toread, link, msg_code;
971 u8 code, routine;
973 cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
974 cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
975 cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
976 /* at most 20 bytes are available... thanks to Daniela :) */
977 toread = size < 20 ? size : 20;
978 cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
979 cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
980 cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
982 printk(KERN_INFO "cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n");
983 printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf);
984 printk(KERN_INFO "Log message code=0x%X\n", msg_code);
985 printk(KERN_INFO "Link=%d\n", link);
986 printk(KERN_INFO "log code=0x%X\n", code);
987 printk(KERN_INFO "log routine=0x%X\n", routine);
988 printk(KERN_INFO "Message size=%d\n", size);
989 hex_dump("Message", bf, toread);
990 #endif
993 /* STATISTIC interrupt handler. */
994 static void cycx_x25_irq_stat(struct cycx_device *card,
995 struct cycx_x25_cmd *cmd)
997 cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
998 sizeof(card->u.x.stats));
999 hex_dump("cycx_x25_irq_stat", (unsigned char*)&card->u.x.stats,
1000 sizeof(card->u.x.stats));
1001 cycx_x25_dump_stats(&card->u.x.stats);
1002 wake_up_interruptible(&card->wait_stats);
1005 /* Spurious interrupt handler.
1006 * o print a warning
1007 * If number of spurious interrupts exceeded some limit, then ??? */
1008 static void cycx_x25_irq_spurious(struct cycx_device *card,
1009 struct cycx_x25_cmd *cmd)
1011 printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n",
1012 card->devname, cmd->command);
1014 #ifdef CYCLOMX_X25_DEBUG
1015 static void hex_dump(char *msg, unsigned char *p, int len)
1017 unsigned char hex[1024],
1018 * phex = hex;
1020 if (len >= (sizeof(hex) / 2))
1021 len = (sizeof(hex) / 2) - 1;
1023 while (len--) {
1024 sprintf(phex, "%02x", *p++);
1025 phex += 2;
1028 printk(KERN_INFO "%s: %s\n", msg, hex);
1030 #endif
1032 /* Cyclom 2X Firmware-Specific Functions */
1033 /* Exec X.25 command. */
1034 static int x25_exec(struct cycx_device *card, int command, int link,
1035 void *d1, int len1, void *d2, int len2)
1037 struct cycx_x25_cmd c;
1038 unsigned long flags;
1039 u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
1040 u8 retry = CYCX_X25_MAX_CMD_RETRY;
1041 int err = 0;
1043 c.command = command;
1044 c.link = link;
1045 c.len = len1 + len2;
1047 spin_lock_irqsave(&card->u.x.lock, flags);
1049 /* write command */
1050 cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
1052 /* write X.25 data */
1053 if (d1) {
1054 cycx_poke(&card->hw, addr, d1, len1);
1056 if (d2) {
1057 if (len2 > 254) {
1058 u32 addr1 = 0xA00 + 0x400 * link;
1060 cycx_poke(&card->hw, addr + len1, d2, 249);
1061 cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
1062 len2 - 249);
1063 } else
1064 cycx_poke(&card->hw, addr + len1, d2, len2);
1068 /* generate interruption, executing command */
1069 cycx_intr(&card->hw);
1071 /* wait till card->mbox == 0 */
1072 do {
1073 err = cycx_exec(card->mbox);
1074 } while (retry-- && err);
1076 spin_unlock_irqrestore(&card->u.x.lock, flags);
1078 return err;
1081 /* Configure adapter. */
1082 static int cycx_x25_configure(struct cycx_device *card,
1083 struct cycx_x25_config *conf)
1085 struct {
1086 u16 nlinks;
1087 struct cycx_x25_config conf[2];
1088 } x25_cmd_conf;
1090 memset(&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1091 x25_cmd_conf.nlinks = 2;
1092 x25_cmd_conf.conf[0] = *conf;
1093 /* FIXME: we need to find a way in the wanrouter framework
1094 to configure the second link, for now lets use it
1095 with the same config from the first link, fixing
1096 the interface type to RS232, the speed in 38400 and
1097 the clock to external */
1098 x25_cmd_conf.conf[1] = *conf;
1099 x25_cmd_conf.conf[1].link = 1;
1100 x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1101 x25_cmd_conf.conf[1].clock = 8;
1102 x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1104 cycx_x25_dump_config(&x25_cmd_conf.conf[0]);
1105 cycx_x25_dump_config(&x25_cmd_conf.conf[1]);
1107 return x25_exec(card, X25_CONFIG, 0,
1108 &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1111 /* Get protocol statistics. */
1112 static int cycx_x25_get_stats(struct cycx_device *card)
1114 /* the firmware expects 20 in the size field!!!
1115 thanks to Daniela */
1116 int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1118 if (err)
1119 return err;
1121 interruptible_sleep_on(&card->wait_stats);
1123 if (signal_pending(current))
1124 return -EINTR;
1126 card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1127 card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1128 card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1129 card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1130 card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1131 card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1132 card->wandev.stats.rx_dropped = 0; /* not available from fw */
1133 card->wandev.stats.rx_errors = 0; /* not available from fw */
1134 card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1135 card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1136 card->wandev.stats.tx_dropped = 0; /* not available from fw */
1137 card->wandev.stats.collisions = 0; /* not available from fw */
1138 card->wandev.stats.tx_errors = 0; /* not available from fw */
1140 cycx_x25_dump_devs(&card->wandev);
1142 return 0;
1145 /* return the number of nibbles */
1146 static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1148 int i = 0;
1150 if (*nibble && *s) {
1151 d[i] |= *s++ - '0';
1152 *nibble = 0;
1153 ++i;
1156 while (*s) {
1157 d[i] = (*s - '0') << 4;
1158 if (*(s + 1))
1159 d[i] |= *(s + 1) - '0';
1160 else {
1161 *nibble = 1;
1162 break;
1164 ++i;
1165 s += 2;
1168 return i;
1171 static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1173 if (nibble) {
1174 *d++ = '0' + (*s++ & 0x0F);
1175 --len;
1178 while (len) {
1179 *d++ = '0' + (*s >> 4);
1181 if (--len) {
1182 *d++ = '0' + (*s & 0x0F);
1183 --len;
1184 } else break;
1186 ++s;
1189 *d = '\0';
1192 /* Place X.25 call. */
1193 static int x25_place_call(struct cycx_device *card,
1194 struct cycx_x25_channel *chan)
1196 int err = 0,
1197 len;
1198 char d[64],
1199 nibble = 0,
1200 mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1201 remotelen = strlen(chan->addr);
1202 u8 key;
1204 if (card->u.x.connection_keys == ~0U) {
1205 printk(KERN_INFO "%s: too many simultaneous connection "
1206 "requests!\n", card->devname);
1207 return -EAGAIN;
1210 key = ffz(card->u.x.connection_keys);
1211 set_bit(key, (void*)&card->u.x.connection_keys);
1212 ++key;
1213 dprintk(1, KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1214 memset(d, 0, sizeof(d));
1215 d[1] = key; /* user key */
1216 d[2] = 0x10;
1217 d[4] = 0x0B;
1219 len = byte_to_nibble(chan->addr, d + 6, &nibble);
1221 if (chan->local_addr)
1222 len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
1224 if (nibble)
1225 ++len;
1227 d[5] = mylen << 4 | remotelen;
1228 d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
1230 if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1231 &d, 7 + len + 1, NULL, 0)) != 0)
1232 clear_bit(--key, (void*)&card->u.x.connection_keys);
1233 else
1234 chan->lcn = -key;
1236 return err;
1239 /* Place X.25 CONNECT RESPONSE. */
1240 static int cycx_x25_connect_response(struct cycx_device *card,
1241 struct cycx_x25_channel *chan)
1243 u8 d[8];
1245 memset(d, 0, sizeof(d));
1246 d[0] = d[3] = chan->lcn;
1247 d[2] = 0x10;
1248 d[4] = 0x0F;
1249 d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
1251 return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
1254 /* Place X.25 DISCONNECT RESPONSE. */
1255 static int cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
1256 u8 lcn)
1258 char d[5];
1260 memset(d, 0, sizeof(d));
1261 d[0] = d[3] = lcn;
1262 d[2] = 0x10;
1263 d[4] = 0x17;
1265 return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
1268 /* Clear X.25 call. */
1269 static int x25_clear_call(struct cycx_device *card, u8 link, u8 lcn, u8 cause,
1270 u8 diagn)
1272 u8 d[7];
1274 memset(d, 0, sizeof(d));
1275 d[0] = d[3] = lcn;
1276 d[2] = 0x10;
1277 d[4] = 0x13;
1278 d[5] = cause;
1279 d[6] = diagn;
1281 return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
1284 /* Send X.25 data packet. */
1285 static int cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
1286 int len, void *buf)
1288 u8 d[] = "?\xFF\x10??";
1290 d[0] = d[3] = lcn;
1291 d[4] = bitm;
1293 return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
1296 /* Miscellaneous */
1297 /* Find network device by its channel number. */
1298 static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
1299 s16 lcn)
1301 struct net_device *dev = wandev->dev;
1302 struct cycx_x25_channel *chan;
1304 while (dev) {
1305 chan = netdev_priv(dev);
1307 if (chan->lcn == lcn)
1308 break;
1309 dev = chan->slave;
1311 return dev;
1314 /* Find network device by its remote dte address. */
1315 static struct net_device *
1316 cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte)
1318 struct net_device *dev = wandev->dev;
1319 struct cycx_x25_channel *chan;
1321 while (dev) {
1322 chan = netdev_priv(dev);
1324 if (!strcmp(chan->addr, dte))
1325 break;
1326 dev = chan->slave;
1328 return dev;
1331 /* Initiate connection on the logical channel.
1332 * o for PVC we just get channel configuration
1333 * o for SVCs place an X.25 call
1335 * Return: 0 connected
1336 * >0 connection in progress
1337 * <0 failure */
1338 static int cycx_x25_chan_connect(struct net_device *dev)
1340 struct cycx_x25_channel *chan = netdev_priv(dev);
1341 struct cycx_device *card = chan->card;
1343 if (chan->svc) {
1344 if (!chan->addr[0])
1345 return -EINVAL; /* no destination address */
1347 dprintk(1, KERN_INFO "%s: placing X.25 call to %s...\n",
1348 card->devname, chan->addr);
1350 if (x25_place_call(card, chan))
1351 return -EIO;
1353 cycx_x25_set_chan_state(dev, WAN_CONNECTING);
1354 return 1;
1355 } else
1356 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
1358 return 0;
1361 /* Disconnect logical channel.
1362 * o if SVC then clear X.25 call */
1363 static void cycx_x25_chan_disconnect(struct net_device *dev)
1365 struct cycx_x25_channel *chan = netdev_priv(dev);
1367 if (chan->svc) {
1368 x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1369 cycx_x25_set_chan_state(dev, WAN_DISCONNECTING);
1370 } else
1371 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
1374 /* Called by kernel timer */
1375 static void cycx_x25_chan_timer(unsigned long d)
1377 struct net_device *dev = (struct net_device *)d;
1378 struct cycx_x25_channel *chan = netdev_priv(dev);
1380 if (chan->state == WAN_CONNECTED)
1381 cycx_x25_chan_disconnect(dev);
1382 else
1383 printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
1384 chan->card->devname, __func__, dev->name);
1387 /* Set logical channel state. */
1388 static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
1390 struct cycx_x25_channel *chan = netdev_priv(dev);
1391 struct cycx_device *card = chan->card;
1392 unsigned long flags;
1393 char *string_state = NULL;
1395 spin_lock_irqsave(&card->lock, flags);
1397 if (chan->state != state) {
1398 if (chan->svc && chan->state == WAN_CONNECTED)
1399 del_timer(&chan->timer);
1401 switch (state) {
1402 case WAN_CONNECTED:
1403 string_state = "connected!";
1404 *(__be16*)dev->dev_addr = htons(chan->lcn);
1405 netif_wake_queue(dev);
1406 reset_timer(dev);
1408 if (chan->protocol == ETH_P_X25)
1409 cycx_x25_chan_send_event(dev, 1);
1411 break;
1412 case WAN_CONNECTING:
1413 string_state = "connecting...";
1414 break;
1415 case WAN_DISCONNECTING:
1416 string_state = "disconnecting...";
1417 break;
1418 case WAN_DISCONNECTED:
1419 string_state = "disconnected!";
1421 if (chan->svc) {
1422 *(unsigned short*)dev->dev_addr = 0;
1423 chan->lcn = 0;
1426 if (chan->protocol == ETH_P_X25)
1427 cycx_x25_chan_send_event(dev, 2);
1429 netif_wake_queue(dev);
1430 break;
1433 printk(KERN_INFO "%s: interface %s %s\n", card->devname,
1434 dev->name, string_state);
1435 chan->state = state;
1438 spin_unlock_irqrestore(&card->lock, flags);
1441 /* Send packet on a logical channel.
1442 * When this function is called, tx_skb field of the channel data space
1443 * points to the transmit socket buffer. When transmission is complete,
1444 * release socket buffer and reset 'tbusy' flag.
1446 * Return: 0 - transmission complete
1447 * 1 - busy
1449 * Notes:
1450 * 1. If packet length is greater than MTU for this channel, we'll fragment
1451 * the packet into 'complete sequence' using M-bit.
1452 * 2. When transmission is complete, an event notification should be issued
1453 * to the router. */
1454 static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
1456 struct cycx_x25_channel *chan = netdev_priv(dev);
1457 struct cycx_device *card = chan->card;
1458 int bitm = 0; /* final packet */
1459 unsigned len = skb->len;
1461 if (skb->len > card->wandev.mtu) {
1462 len = card->wandev.mtu;
1463 bitm = 0x10; /* set M-bit (more data) */
1466 if (cycx_x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1467 return 1;
1469 if (bitm) {
1470 skb_pull(skb, len);
1471 return 1;
1474 ++chan->ifstats.tx_packets;
1475 chan->ifstats.tx_bytes += len;
1477 return 0;
1480 /* Send event (connection, disconnection, etc) to X.25 socket layer */
1482 static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
1484 struct sk_buff *skb;
1485 unsigned char *ptr;
1487 if ((skb = dev_alloc_skb(1)) == NULL) {
1488 printk(KERN_ERR "%s: out of memory\n", __func__);
1489 return;
1492 ptr = skb_put(skb, 1);
1493 *ptr = event;
1495 skb->protocol = x25_type_trans(skb, dev);
1496 netif_rx(skb);
1499 /* Convert line speed in bps to a number used by cyclom 2x code. */
1500 static u8 bps_to_speed_code(u32 bps)
1502 u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1504 if (bps >= 512000) number = 8;
1505 else if (bps >= 256000) number = 7;
1506 else if (bps >= 64000) number = 6;
1507 else if (bps >= 38400) number = 5;
1508 else if (bps >= 19200) number = 4;
1509 else if (bps >= 9600) number = 3;
1510 else if (bps >= 4800) number = 2;
1511 else if (bps >= 2400) number = 1;
1513 return number;
1516 /* log base 2 */
1517 static u8 cycx_log2(u32 n)
1519 u8 log = 0;
1521 if (!n)
1522 return 0;
1524 while (n > 1) {
1525 n >>= 1;
1526 ++log;
1529 return log;
1532 /* Convert decimal string to unsigned integer.
1533 * If len != 0 then only 'len' characters of the string are converted. */
1534 static unsigned dec_to_uint(u8 *str, int len)
1536 unsigned val = 0;
1538 if (!len)
1539 len = strlen(str);
1541 for (; len && isdigit(*str); ++str, --len)
1542 val = (val * 10) + (*str - (unsigned) '0');
1544 return val;
1547 static void reset_timer(struct net_device *dev)
1549 struct cycx_x25_channel *chan = netdev_priv(dev);
1551 if (chan->svc)
1552 mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
1554 #ifdef CYCLOMX_X25_DEBUG
1555 static void cycx_x25_dump_config(struct cycx_x25_config *conf)
1557 printk(KERN_INFO "X.25 configuration\n");
1558 printk(KERN_INFO "-----------------\n");
1559 printk(KERN_INFO "link number=%d\n", conf->link);
1560 printk(KERN_INFO "line speed=%d\n", conf->speed);
1561 printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1562 printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1563 printk(KERN_INFO "level 2 window=%d\n", conf->n2win);
1564 printk(KERN_INFO "level 3 window=%d\n", conf->n3win);
1565 printk(KERN_INFO "# logical channels=%d\n", conf->nvc);
1566 printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1567 printk(KERN_INFO "my address=%d\n", conf->locaddr);
1568 printk(KERN_INFO "remote address=%d\n", conf->remaddr);
1569 printk(KERN_INFO "t1=%d seconds\n", conf->t1);
1570 printk(KERN_INFO "t2=%d seconds\n", conf->t2);
1571 printk(KERN_INFO "t21=%d seconds\n", conf->t21);
1572 printk(KERN_INFO "# PVCs=%d\n", conf->npvc);
1573 printk(KERN_INFO "t23=%d seconds\n", conf->t23);
1574 printk(KERN_INFO "flags=0x%x\n", conf->flags);
1577 static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
1579 printk(KERN_INFO "X.25 statistics\n");
1580 printk(KERN_INFO "--------------\n");
1581 printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1582 printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1583 printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1584 printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1585 printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1586 printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1587 printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1588 printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1589 printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1590 printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1593 static void cycx_x25_dump_devs(struct wan_device *wandev)
1595 struct net_device *dev = wandev->dev;
1597 printk(KERN_INFO "X.25 dev states\n");
1598 printk(KERN_INFO "name: addr: txoff: protocol:\n");
1599 printk(KERN_INFO "---------------------------------------\n");
1601 while(dev) {
1602 struct cycx_x25_channel *chan = netdev_priv(dev);
1604 printk(KERN_INFO "%-5.5s %-15.15s %d ETH_P_%s\n",
1605 chan->name, chan->addr, netif_queue_stopped(dev),
1606 chan->protocol == ETH_P_IP ? "IP" : "X25");
1607 dev = chan->slave;
1611 #endif /* CYCLOMX_X25_DEBUG */
1612 /* End */