~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/wan/cycx_x25.c

Version: ~ [ 2.4.21-47.EL ] ~ [ 2.6.9-67.EL ] ~ [ 2.6.18-128.el5 ] ~ [ 2.6.18-164.el5 ] ~
Architecture: ~ [ i386 ] ~ [ x86_64 ] ~

  1 /*
  2 * cycx_x25.c    Cyclom 2X WAN Link Driver.  X.25 module.
  3 *
  4 * Author:       Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  5 *
  6 * Copyright:    (c) 1998-2003 Arnaldo Carvalho de Melo
  7 *
  8 * Based on sdla_x25.c by Gene Kozin <genek@compuserve.com>
  9 *
 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.
 77 */
 78 
 79 #define CYCLOMX_X25_DEBUG 1
 80 
 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/slab.h>         /* kmalloc(), kfree() */
 88 #include <linux/stddef.h>       /* offsetof(), etc. */
 89 #include <linux/wanrouter.h>    /* WAN router definitions */
 90 
 91 #include <asm/byteorder.h>      /* htons(), etc. */
 92 
 93 #include <linux/cyclomx.h>      /* Cyclom 2X common user API definitions */
 94 #include <linux/cycx_x25.h>     /* X.25 firmware API definitions */
 95 
 96 #include <net/x25device.h>
 97 
 98 /* Defines & Macros */
 99 #define CYCX_X25_MAX_CMD_RETRY 5
100 #define CYCX_X25_CHAN_MTU 2048  /* unfragmented logical channel MTU */
101 
102 /* Data Structures */
103 /* This is an extension of the 'struct net_device' we create for each network
104    interface to keep the rest of X.25 channel-specific data. */
105 struct cycx_x25_channel {
106         /* This member must be first. */
107         struct net_device *slave;       /* WAN slave */
108 
109         char name[WAN_IFNAME_SZ+1];     /* interface name, ASCIIZ */
110         char addr[WAN_ADDRESS_SZ+1];    /* media address, ASCIIZ */
111         char *local_addr;               /* local media address, ASCIIZ -
112                                            svc thru crossover cable */
113         s16 lcn;                        /* logical channel number/conn.req.key*/
114         u8 link;
115         struct timer_list timer;        /* timer used for svc channel disc. */
116         u16 protocol;                   /* ethertype, 0 - multiplexed */
117         u8 svc;                         /* 0 - permanent, 1 - switched */
118         u8 state;                       /* channel state */
119         u8 drop_sequence;               /* mark sequence for dropping */
120         u32 idle_tmout;                 /* sec, before disconnecting */
121         struct sk_buff *rx_skb;         /* receive socket buffer */
122         struct cycx_device *card;       /* -> owner */
123         struct net_device_stats ifstats;/* interface statistics */
124 };
125 
126 /* Function Prototypes */
127 /* WAN link driver entry points. These are called by the WAN router module. */
128 static int cycx_wan_update(struct wan_device *wandev),
129            cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
130                            wanif_conf_t *conf),
131            cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
132 
133 /* Network device interface */
134 static int cycx_netdevice_init(struct net_device *dev),
135            cycx_netdevice_open(struct net_device *dev),
136            cycx_netdevice_stop(struct net_device *dev),
137            cycx_netdevice_hard_header(struct sk_buff *skb,
138                                      struct net_device *dev, u16 type,
139                                      void *daddr, void *saddr, unsigned len),
140            cycx_netdevice_rebuild_header(struct sk_buff *skb),
141            cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
142                                           struct net_device *dev);
143 
144 static struct net_device_stats *
145                         cycx_netdevice_get_stats(struct net_device *dev);
146 
147 /* Interrupt handlers */
148 static void cycx_x25_irq_handler(struct cycx_device *card),
149             cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
150             cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
151             cycx_x25_irq_log(struct cycx_device *card,
152                              struct cycx_x25_cmd *cmd),
153             cycx_x25_irq_stat(struct cycx_device *card,
154                               struct cycx_x25_cmd *cmd),
155             cycx_x25_irq_connect_confirm(struct cycx_device *card,
156                                          struct cycx_x25_cmd *cmd),
157             cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
158                                             struct cycx_x25_cmd *cmd),
159             cycx_x25_irq_connect(struct cycx_device *card,
160                                  struct cycx_x25_cmd *cmd),
161             cycx_x25_irq_disconnect(struct cycx_device *card,
162                                     struct cycx_x25_cmd *cmd),
163             cycx_x25_irq_spurious(struct cycx_device *card,
164                                   struct cycx_x25_cmd *cmd);
165 
166 /* X.25 firmware interface functions */
167 static int cycx_x25_configure(struct cycx_device *card,
168                               struct cycx_x25_config *conf),
169            cycx_x25_get_stats(struct cycx_device *card),
170            cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
171                          int len, void *buf),
172            cycx_x25_connect_response(struct cycx_device *card,
173                                 struct cycx_x25_channel *chan),
174            cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
175                                         u8 lcn);
176 
177 /* channel functions */
178 static int cycx_x25_chan_connect(struct net_device *dev),
179            cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb);
180 
181 static void cycx_x25_chan_disconnect(struct net_device *dev),
182             cycx_x25_chan_send_event(struct net_device *dev, u8 event);
183 
184 /* Miscellaneous functions */
185 static void cycx_x25_set_chan_state(struct net_device *dev, u8 state),
186             cycx_x25_chan_timer(unsigned long d);
187 
188 static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble),
189             reset_timer(struct net_device *dev);
190 
191 static u8 bps_to_speed_code(u32 bps);
192 static u8 cycx_log2(u32 n);
193 
194 static unsigned dec_to_uint(u8 *str, int len);
195 
196 static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
197                                                   s16 lcn);
198 static struct net_device *
199         cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
200 
201 #ifdef CYCLOMX_X25_DEBUG
202 static void hex_dump(char *msg, unsigned char *p, int len);
203 static void cycx_x25_dump_config(struct cycx_x25_config *conf);
204 static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
205 static void cycx_x25_dump_devs(struct wan_device *wandev);
206 #else
207 #define hex_dump(msg, p, len)
208 #define cycx_x25_dump_config(conf)
209 #define cycx_x25_dump_stats(stats)
210 #define cycx_x25_dump_devs(wandev)
211 #endif
212 /* Public Functions */
213 
214 /* X.25 Protocol Initialization routine.
215  *
216  * This routine is called by the main Cyclom 2X module during setup.  At this
217  * point adapter is completely initialized and X.25 firmware is running.
218  *  o configure adapter
219  *  o initialize protocol-specific fields of the adapter data space.
220  *
221  * Return:      0       o.k.
222  *              < 0     failure.  */
223 int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
224 {
225         struct cycx_x25_config cfg;
226 
227         /* Verify configuration ID */
228         if (conf->config_id != WANCONFIG_X25) {
229                 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
230                                  card->devname, conf->config_id);
231                 return -EINVAL;
232         }
233 
234         /* Initialize protocol-specific fields */
235         card->mbox  = card->hw.dpmbase + X25_MBOX_OFFS;
236         card->u.x.connection_keys = 0;
237         spin_lock_init(&card->u.x.lock);
238 
239         /* Configure adapter. Here we set reasonable defaults, then parse
240          * device configuration structure and set configuration options.
241          * Most configuration options are verified and corrected (if
242          * necessary) since we can't rely on the adapter to do so and don't
243          * want it to fail either. */
244         memset(&cfg, 0, sizeof(cfg));
245         cfg.link = 0;
246         cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
247         cfg.speed = bps_to_speed_code(conf->bps);
248         cfg.n3win = 7;
249         cfg.n2win = 2;
250         cfg.n2 = 5;
251         cfg.nvc = 1;
252         cfg.npvc = 1;
253         cfg.flags = 0x02; /* default = V35 */
254         cfg.t1 = 10;   /* line carrier timeout */
255         cfg.t2 = 29;   /* tx timeout */
256         cfg.t21 = 180; /* CALL timeout */
257         cfg.t23 = 180; /* CLEAR timeout */
258 
259         /* adjust MTU */
260         if (!conf->mtu || conf->mtu >= 512)
261                 card->wandev.mtu = 512;
262         else if (conf->mtu >= 256)
263                 card->wandev.mtu = 256;
264         else if (conf->mtu >= 128)
265                 card->wandev.mtu = 128;
266         else
267                 card->wandev.mtu = 64;
268 
269         cfg.pktlen = cycx_log2(card->wandev.mtu);
270 
271         if (conf->station == WANOPT_DTE) {
272                 cfg.locaddr = 3; /* DTE */
273                 cfg.remaddr = 1; /* DCE */
274         } else {
275                 cfg.locaddr = 1; /* DCE */
276                 cfg.remaddr = 3; /* DTE */
277         }
278 
279         if (conf->interface == WANOPT_RS232)
280                 cfg.flags = 0;      /* FIXME just reset the 2nd bit */
281 
282         if (conf->u.x25.hi_pvc) {
283                 card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
284                 card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
285         }
286 
287         if (conf->u.x25.hi_svc) {
288                 card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
289                 card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
290         }
291 
292         if (card->u.x.lo_pvc == 255)
293                 cfg.npvc = 0;
294         else
295                 cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
296 
297         cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
298 
299         if (conf->u.x25.hdlc_window)
300                 cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
301 
302         if (conf->u.x25.pkt_window)
303                 cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
304 
305         if (conf->u.x25.t1)
306                 cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
307 
308         if (conf->u.x25.t2)
309                 cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
310 
311         if (conf->u.x25.t11_t21)
312                 cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
313 
314         if (conf->u.x25.t13_t23)
315                 cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
316 
317         if (conf->u.x25.n2)
318                 cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
319 
320         /* initialize adapter */
321         if (cycx_x25_configure(card, &cfg))
322                 return -EIO;
323 
324         /* Initialize protocol-specific fields of adapter data space */
325         card->wandev.bps        = conf->bps;
326         card->wandev.interface  = conf->interface;
327         card->wandev.clocking   = conf->clocking;
328         card->wandev.station    = conf->station;
329         card->isr               = cycx_x25_irq_handler;
330         card->exec              = NULL;
331         card->wandev.update     = cycx_wan_update;
332         card->wandev.new_if     = cycx_wan_new_if;
333         card->wandev.del_if     = cycx_wan_del_if;
334         card->wandev.state      = WAN_DISCONNECTED;
335 
336         return 0;
337 }
338 
339 /* WAN Device Driver Entry Points */
340 /* Update device status & statistics. */
341 static int cycx_wan_update(struct wan_device *wandev)
342 {
343         /* sanity checks */
344         if (!wandev || !wandev->private)
345                 return -EFAULT;
346 
347         if (wandev->state == WAN_UNCONFIGURED)
348                 return -ENODEV;
349 
350         cycx_x25_get_stats(wandev->private);
351 
352         return 0;
353 }
354 
355 /* Create new logical channel.
356  * This routine is called by the router when ROUTER_IFNEW IOCTL is being
357  * handled.
358  * o parse media- and hardware-specific configuration
359  * o make sure that a new channel can be created
360  * o allocate resources, if necessary
361  * o prepare network device structure for registration.
362  *
363  * Return:      0       o.k.
364  *              < 0     failure (channel will not be created) */
365 static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
366                            wanif_conf_t *conf)
367 {
368         struct cycx_device *card = wandev->private;
369         struct cycx_x25_channel *chan;
370         int err = 0;
371 
372         if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
373                 printk(KERN_INFO "%s: invalid interface name!\n",
374                        card->devname);
375                 return -EINVAL;
376         }
377 
378         /* allocate and initialize private data */
379         chan = kmalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL);
380         if (!chan)
381                 return -ENOMEM;
382 
383         memset(chan, 0, sizeof(*chan));
384         strcpy(chan->name, conf->name);
385         chan->card = card;
386         chan->link = conf->port;
387         chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
388         chan->rx_skb = NULL;
389         /* only used in svc connected thru crossover cable */
390         chan->local_addr = NULL;
391 
392         if (conf->addr[0] == '@') {     /* SVC */
393                 int len = strlen(conf->local_addr);
394 
395                 if (len) {
396                         if (len > WAN_ADDRESS_SZ) {
397                                 printk(KERN_ERR "%s: %s local addr too long!\n",
398                                                 wandev->name, chan->name);
399                                 kfree(chan);
400                                 return -EINVAL;
401                         } else {
402                                 chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
403 
404                                 if (!chan->local_addr) {
405                                         kfree(chan);
406                                         return -ENOMEM;
407                                 }
408                         }
409 
410                         strncpy(chan->local_addr, conf->local_addr,
411                                 WAN_ADDRESS_SZ);
412                 }
413 
414                 chan->svc = 1;
415                 strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
416                 init_timer(&chan->timer);
417                 chan->timer.function    = cycx_x25_chan_timer;
418                 chan->timer.data        = (unsigned long)dev;
419 
420                 /* Set channel timeouts (default if not specified) */
421                 chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
422         } else if (isdigit(conf->addr[0])) {    /* PVC */
423                 s16 lcn = dec_to_uint(conf->addr, 0);
424 
425                 if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
426                         chan->lcn = lcn;
427                 else {
428                         printk(KERN_ERR
429                                 "%s: PVC %u is out of range on interface %s!\n",
430                                 wandev->name, lcn, chan->name);
431                         err = -EINVAL;
432                 }
433         } else {
434                 printk(KERN_ERR "%s: invalid media address on interface %s!\n",
435                                 wandev->name, chan->name);
436                 err = -EINVAL;
437         }
438 
439         if (err) {
440                 kfree(chan->local_addr);
441                 kfree(chan);
442                 return err;
443         }
444 
445         /* prepare network device data space for registration */
446         strcpy(dev->name, chan->name);
447         dev->init = cycx_netdevice_init;
448         dev->priv = chan;
449 
450         return 0;
451 }
452 
453 /* Delete logical channel. */
454 static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
455 {
456         if (dev->priv) {
457                 struct cycx_x25_channel *chan = dev->priv;
458 
459                 if (chan->svc) {
460                         kfree(chan->local_addr);
461                         if (chan->state == WAN_CONNECTED)
462                                 del_timer(&chan->timer);
463                 }
464 
465                 kfree(chan);
466                 dev->priv = NULL;
467         }
468 
469         return 0;
470 }
471 
472 /* Network Device Interface */
473 /* Initialize Linux network interface.
474  *
475  * This routine is called only once for each interface, during Linux network
476  * interface registration.  Returning anything but zero will fail interface
477  * registration. */
478 static int cycx_netdevice_init(struct net_device *dev)
479 {
480         struct cycx_x25_channel *chan = dev->priv;
481         struct cycx_device *card = chan->card;
482         struct wan_device *wandev = &card->wandev;
483 
484         /* Initialize device driver entry points */
485         dev->open               = cycx_netdevice_open;
486         dev->stop               = cycx_netdevice_stop;
487         dev->hard_header        = cycx_netdevice_hard_header;
488         dev->rebuild_header     = cycx_netdevice_rebuild_header;
489         dev->hard_start_xmit    = cycx_netdevice_hard_start_xmit;
490         dev->get_stats          = cycx_netdevice_get_stats;
491 
492         /* Initialize media-specific parameters */
493         dev->mtu                = CYCX_X25_CHAN_MTU;
494         dev->type               = ARPHRD_HWX25; /* ARP h/w type */
495         dev->hard_header_len    = 0;            /* media header length */
496         dev->addr_len           = 0;            /* hardware address length */
497 
498         if (!chan->svc)
499                 *(u16*)dev->dev_addr = htons(chan->lcn);
500 
501         /* Initialize hardware parameters (just for reference) */
502         dev->irq                = wandev->irq;
503         dev->dma                = wandev->dma;
504         dev->base_addr          = wandev->ioport;
505         dev->mem_start          = (unsigned long)wandev->maddr;
506         dev->mem_end            = (unsigned long)(wandev->maddr +
507                                                   wandev->msize - 1);
508         dev->flags              |= IFF_NOARP;
509 
510         /* Set transmit buffer queue length */
511         dev->tx_queue_len       = 10;
512         SET_MODULE_OWNER(dev);
513 
514         /* Initialize socket buffers */
515         cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
516 
517         return 0;
518 }
519 
520 /* Open network interface.
521  * o prevent module from unloading by incrementing use count
522  * o if link is disconnected then initiate connection
523  *
524  * Return 0 if O.k. or errno.  */
525 static int cycx_netdevice_open(struct net_device *dev)
526 {
527         if (netif_running(dev))
528                 return -EBUSY; /* only one open is allowed */
529 
530         netif_start_queue(dev);
531         return 0;
532 }
533 
534 /* Close network interface.
535  * o reset flags.
536  * o if there's no more open channels then disconnect physical link. */
537 static int cycx_netdevice_stop(struct net_device *dev)
538 {
539         struct cycx_x25_channel *chan = dev->priv;
540 
541         netif_stop_queue(dev);
542 
543         if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
544                 cycx_x25_chan_disconnect(dev);
545 
546         return 0;
547 }
548 
549 /* Build media header.
550  * o encapsulate packet according to encapsulation type.
551  *
552  * The trick here is to put packet type (Ethertype) into 'protocol' field of
553  * the socket buffer, so that we don't forget it.  If encapsulation fails,
554  * set skb->protocol to 0 and discard packet later.
555  *
556  * Return:      media header length. */
557 static int cycx_netdevice_hard_header(struct sk_buff *skb,
558                                       struct net_device *dev, u16 type,
559                                       void *daddr, void *saddr, unsigned len)
560 {
561         skb->protocol = type;
562 
563         return dev->hard_header_len;
564 }
565 
566 /* * Re-build media header.
567  * Return:      1       physical address resolved.
568  *              0       physical address not resolved */
569 static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
570 {
571         return 1;
572 }
573 
574 /* Send a packet on a network interface.
575  * o set busy flag (marks start of the transmission).
576  * o check link state. If link is not up, then drop the packet.
577  * o check channel status. If it's down then initiate a call.
578  * o pass a packet to corresponding WAN device.
579  * o free socket buffer
580  *
581  * Return:      0       complete (socket buffer must be freed)
582  *              non-0   packet may be re-transmitted (tbusy must be set)
583  *
584  * Notes:
585  * 1. This routine is called either by the protocol stack or by the "net
586  *    bottom half" (with interrupts enabled).
587  * 2. Setting tbusy flag will inhibit further transmit requests from the
588  *    protocol stack and can be used for flow control with protocol layer. */
589 static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
590                                           struct net_device *dev)
591 {
592         struct cycx_x25_channel *chan = dev->priv;
593         struct cycx_device *card = chan->card;
594 
595         if (!chan->svc)
596                 chan->protocol = skb->protocol;
597 
598         if (card->wandev.state != WAN_CONNECTED)
599                 ++chan->ifstats.tx_dropped;
600         else if (chan->svc && chan->protocol &&
601                  chan->protocol != skb->protocol) {
602                 printk(KERN_INFO
603                        "%s: unsupported Ethertype 0x%04X on interface %s!\n",
604                        card->devname, skb->protocol, dev->name);
605                 ++chan->ifstats.tx_errors;
606         } else if (chan->protocol == ETH_P_IP) {
607                 switch (chan->state) {
608                 case WAN_DISCONNECTED:
609                         if (cycx_x25_chan_connect(dev)) {
610                                 netif_stop_queue(dev);
611                                 return -EBUSY;
612                         }
613                         /* fall thru */
614                 case WAN_CONNECTED:
615                         reset_timer(dev);
616                         dev->trans_start = jiffies;
617                         netif_stop_queue(dev);
618 
619                         if (cycx_x25_chan_send(dev, skb))
620                                 return -EBUSY;
621 
622                         break;
623                 default:
624                         ++chan->ifstats.tx_dropped;
625                         ++card->wandev.stats.tx_dropped;
626         }
627         } else { /* chan->protocol == ETH_P_X25 */
628                 switch (skb->data[0]) {
629                 case 0: break;
630                 case 1: /* Connect request */
631                         cycx_x25_chan_connect(dev);
632                         goto free_packet;
633                 case 2: /* Disconnect request */
634                         cycx_x25_chan_disconnect(dev);
635                         goto free_packet;
636                 default:
637                         printk(KERN_INFO
638                                "%s: unknown %d x25-iface request on %s!\n",
639                                card->devname, skb->data[0], dev->name);
640                         ++chan->ifstats.tx_errors;
641                         goto free_packet;
642                 }
643 
644                 skb_pull(skb, 1); /* Remove control byte */
645                 reset_timer(dev);
646                 dev->trans_start = jiffies;
647                 netif_stop_queue(dev);
648 
649                 if (cycx_x25_chan_send(dev, skb)) {
650                         /* prepare for future retransmissions */
651                         skb_push(skb, 1);
652                         return -EBUSY;
653                 }
654         }
655 
656 free_packet:
657         dev_kfree_skb(skb);
658 
659         return 0;
660 }
661 
662 /* Get Ethernet-style interface statistics.
663  * Return a pointer to struct net_device_stats */
664 static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
665 {
666         struct cycx_x25_channel *chan = dev->priv;
667 
668         return chan ? &chan->ifstats : NULL;
669 }
670 
671 /* Interrupt Handlers */
672 /* X.25 Interrupt Service Routine. */
673 static void cycx_x25_irq_handler(struct cycx_device *card)
674 {
675         struct cycx_x25_cmd cmd;
676         u16 z = 0;
677 
678         card->in_isr = 1;
679         card->buff_int_mode_unbusy = 0;
680         cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
681 
682         switch (cmd.command) {
683         case X25_DATA_INDICATION:
684                 cycx_x25_irq_rx(card, &cmd);
685                 break;
686         case X25_ACK_FROM_VC:
687                 cycx_x25_irq_tx(card, &cmd);
688                 break;
689         case X25_LOG:
690                 cycx_x25_irq_log(card, &cmd);
691                 break;
692         case X25_STATISTIC:
693                 cycx_x25_irq_stat(card, &cmd);
694                 break;
695         case X25_CONNECT_CONFIRM:
696                 cycx_x25_irq_connect_confirm(card, &cmd);
697                 break;
698         case X25_CONNECT_INDICATION:
699                 cycx_x25_irq_connect(card, &cmd);
700                 break;
701         case X25_DISCONNECT_INDICATION:
702                 cycx_x25_irq_disconnect(card, &cmd);
703                 break;
704         case X25_DISCONNECT_CONFIRM:
705                 cycx_x25_irq_disconnect_confirm(card, &cmd);
706                 break;
707         case X25_LINE_ON:
708                 cycx_set_state(card, WAN_CONNECTED);
709                 break;
710         case X25_LINE_OFF:
711                 cycx_set_state(card, WAN_DISCONNECTED);
712                 break;
713         default:
714                 cycx_x25_irq_spurious(card, &cmd);
715                 break;
716         }
717 
718         cycx_poke(&card->hw, 0, &z, sizeof(z));
719         cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
720         card->in_isr = 0;
721 }
722 
723 /* Transmit interrupt handler.
724  *      o Release socket buffer
725  *      o Clear 'tbusy' flag */
726 static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
727 {
728         struct net_device *dev;
729         struct wan_device *wandev = &card->wandev;
730         u8 lcn;
731 
732         cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
733 
734         /* unbusy device and then dev_tint(); */
735         dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
736         if (dev) {
737                 card->buff_int_mode_unbusy = 1;
738                 netif_wake_queue(dev);
739         } else
740                 printk(KERN_ERR "%s:ackvc for inexistent lcn %d\n",
741                                  card->devname, lcn);
742 }
743 
744 /* Receive interrupt handler.
745  * This routine handles fragmented IP packets using M-bit according to the
746  * RFC1356.
747  * o map logical channel number to network interface.
748  * o allocate socket buffer or append received packet to the existing one.
749  * o if M-bit is reset (i.e. it's the last packet in a sequence) then
750  *   decapsulate packet and pass socket buffer to the protocol stack.
751  *
752  * Notes:
753  * 1. When allocating a socket buffer, if M-bit is set then more data is
754  *    coming and we have to allocate buffer for the maximum IP packet size
755  *    expected on this channel.
756  * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
757  *    socket buffers available) the whole packet sequence must be discarded. */
758 static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
759 {
760         struct wan_device *wandev = &card->wandev;
761         struct net_device *dev;
762         struct cycx_x25_channel *chan;
763         struct sk_buff *skb;
764         u8 bitm, lcn;
765         int pktlen = cmd->len - 5;
766 
767         cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
768         cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
769         bitm &= 0x10;
770 
771         dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
772         if (!dev) {
773                 /* Invalid channel, discard packet */
774                 printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
775                                  card->devname, lcn);
776                 return;
777         }
778 
779         chan = dev->priv;
780         reset_timer(dev);
781 
782         if (chan->drop_sequence) {
783                 if (!bitm)
784                         chan->drop_sequence = 0;
785                 else
786                         return;
787         }
788 
789         if ((skb = chan->rx_skb) == NULL) {
790                 /* Allocate new socket buffer */
791                 int bufsize = bitm ? dev->mtu : pktlen;
792 
793                 if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
794                                          bufsize +
795                                          dev->hard_header_len)) == NULL) {
796                         printk(KERN_INFO "%s: no socket buffers available!\n",
797                                          card->devname);
798                         chan->drop_sequence = 1;
799                         ++chan->ifstats.rx_dropped;
800                         return;
801                 }
802 
803                 if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
804                         /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
805                         skb_put(skb, 1);
806 
807                 skb->dev = dev;
808                 skb->protocol = htons(chan->protocol);
809                 chan->rx_skb = skb;
810         }
811 
812         if (skb_tailroom(skb) < pktlen) {
813                 /* No room for the packet. Call off the whole thing! */
814                 dev_kfree_skb_irq(skb);
815                 chan->rx_skb = NULL;
816 
817                 if (bitm)
818                         chan->drop_sequence = 1;
819 
820                 printk(KERN_INFO "%s: unexpectedly long packet sequence "
821                         "on interface %s!\n", card->devname, dev->name);
822                 ++chan->ifstats.rx_length_errors;
823                 return;
824         }
825 
826         /* Append packet to the socket buffer  */
827         cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
828 
829         if (bitm)
830                 return; /* more data is coming */
831 
832         chan->rx_skb = NULL;            /* dequeue packet */
833 
834         ++chan->ifstats.rx_packets;
835         chan->ifstats.rx_bytes += pktlen;
836 
837         skb->mac.raw = skb->data;
838         netif_rx(skb);
839         dev->last_rx = jiffies;         /* timestamp */
840 }
841 
842 /* Connect interrupt handler. */
843 static void cycx_x25_irq_connect(struct cycx_device *card,
844                                  struct cycx_x25_cmd *cmd)
845 {
846         struct wan_device *wandev = &card->wandev;
847         struct net_device *dev = NULL;
848         struct cycx_x25_channel *chan;
849         u8 d[32],
850            loc[24],
851            rem[24];
852         u8 lcn, sizeloc, sizerem;
853 
854         cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
855         cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
856         cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
857 
858         sizerem = sizeloc >> 4;
859         sizeloc &= 0x0F;
860 
861         loc[0] = rem[0] = '\0';
862 
863         if (sizeloc)
864                 nibble_to_byte(d, loc, sizeloc, 0);
865 
866         if (sizerem)
867                 nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
868 
869         dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
870                           __FUNCTION__, lcn, loc, rem);
871 
872         dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
873         if (!dev) {
874                 /* Invalid channel, discard packet */
875                 printk(KERN_INFO "%s: connect not expected: remote %s!\n",
876                                  card->devname, rem);
877                 return;
878         }
879 
880         chan = dev->priv;
881         chan->lcn = lcn;
882         cycx_x25_connect_response(card, chan);
883         cycx_x25_set_chan_state(dev, WAN_CONNECTED);
884 }
885 
886 /* Connect confirm interrupt handler. */
887 static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
888                                          struct cycx_x25_cmd *cmd)
889 {
890         struct wan_device *wandev = &card->wandev;
891         struct net_device *dev;
892         struct cycx_x25_channel *chan;
893         u8 lcn, key;
894 
895         cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
896         cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
897         dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
898                           card->devname, __FUNCTION__, lcn, key);
899 
900         dev = cycx_x25_get_dev_by_lcn(wandev, -key);
901         if (!dev) {
902                 /* Invalid channel, discard packet */
903                 clear_bit(--key, (void*)&card->u.x.connection_keys);
904                 printk(KERN_INFO "%s: connect confirm not expected: lcn %d, "
905                                  "key=%d!\n", card->devname, lcn, key);
906                 return;
907         }
908 
909         clear_bit(--key, (void*)&card->u.x.connection_keys);
910         chan = dev->priv;
911         chan->lcn = lcn;
912         cycx_x25_set_chan_state(dev, WAN_CONNECTED);
913 }
914 
915 /* Disconnect confirm interrupt handler. */
916 static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
917                                             struct cycx_x25_cmd *cmd)
918 {
919         struct wan_device *wandev = &card->wandev;
920         struct net_device *dev;
921         u8 lcn;
922 
923         cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
924         dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
925                           card->devname, __FUNCTION__, lcn);
926         dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
927         if (!dev) {
928                 /* Invalid channel, discard packet */
929                 printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n",
930                                  card->devname, lcn);
931                 return;
932         }
933 
934         cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
935 }
936 
937 /* disconnect interrupt handler. */
938 static void cycx_x25_irq_disconnect(struct cycx_device *card,
939                                     struct cycx_x25_cmd *cmd)
940 {
941         struct wan_device *wandev = &card->wandev;
942         struct net_device *dev;
943         u8 lcn;
944 
945         cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
946         dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn);
947 
948         dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
949         if (dev) {
950                 struct cycx_x25_channel *chan = dev->priv;
951 
952                 cycx_x25_disconnect_response(card, chan->link, lcn);
953                 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
954         } else
955                 cycx_x25_disconnect_response(card, 0, lcn);
956 }
957 
958 /* LOG interrupt handler. */
959 static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd)
960 {
961 #if CYCLOMX_X25_DEBUG
962         char bf[20];
963         u16 size, toread, link, msg_code;
964         u8 code, routine;
965 
966         cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
967         cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
968         cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
969         /* at most 20 bytes are available... thanks to Daniela :) */
970         toread = size < 20 ? size : 20;
971         cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
972         cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
973         cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
974 
975         printk(KERN_INFO "cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n");
976         printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf);
977         printk(KERN_INFO "Log message code=0x%X\n", msg_code);
978         printk(KERN_INFO "Link=%d\n", link);
979         printk(KERN_INFO "log code=0x%X\n", code);
980         printk(KERN_INFO "log routine=0x%X\n", routine);
981         printk(KERN_INFO "Message size=%d\n", size);
982         hex_dump("Message", bf, toread);
983 #endif
984 }
985 
986 /* STATISTIC interrupt handler. */
987 static void cycx_x25_irq_stat(struct cycx_device *card,
988                               struct cycx_x25_cmd *cmd)
989 {
990         cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
991                   sizeof(card->u.x.stats));
992         hex_dump("cycx_x25_irq_stat", (unsigned char*)&card->u.x.stats,
993                  sizeof(card->u.x.stats));
994         cycx_x25_dump_stats(&card->u.x.stats);
995         wake_up_interruptible(&card->wait_stats);
996 }
997 
998 /* Spurious interrupt handler.
999  * o print a warning
1000  * If number of spurious interrupts exceeded some limit, then ??? */
1001 static void cycx_x25_irq_spurious(struct cycx_device *card,
1002                                   struct cycx_x25_cmd *cmd)
1003 {
1004         printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n",
1005                          card->devname, cmd->command);
1006 }
1007 #ifdef CYCLOMX_X25_DEBUG
1008 static void hex_dump(char *msg, unsigned char *p, int len)
1009 {
1010         unsigned char hex[1024],
1011                 * phex = hex;
1012 
1013         if (len >= (sizeof(hex) / 2))
1014                 len = (sizeof(hex) / 2) - 1;
1015 
1016         while (len--) {
1017                 sprintf(phex, "%02x", *p++);
1018                 phex += 2;
1019         }
1020 
1021         printk(KERN_INFO "%s: %s\n", msg, hex);
1022 }
1023 #endif
1024 
1025 /* Cyclom 2X Firmware-Specific Functions */
1026 /* Exec X.25 command. */
1027 static int x25_exec(struct cycx_device *card, int command, int link,
1028                     void *d1, int len1, void *d2, int len2)
1029 {
1030         struct cycx_x25_cmd c;
1031         unsigned long flags;
1032         u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
1033         u8 retry = CYCX_X25_MAX_CMD_RETRY;
1034         int err = 0;
1035 
1036         c.command = command;
1037         c.link = link;
1038         c.len = len1 + len2;
1039 
1040         spin_lock_irqsave(&card->u.x.lock, flags);
1041 
1042         /* write command */
1043         cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
1044 
1045         /* write X.25 data */
1046         if (d1) {
1047                 cycx_poke(&card->hw, addr, d1, len1);
1048 
1049                 if (d2) {
1050                         if (len2 > 254) {
1051                                 u32 addr1 = 0xA00 + 0x400 * link;
1052 
1053                                 cycx_poke(&card->hw, addr + len1, d2, 249);
1054                                 cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
1055                                           len2 - 249);
1056                         } else
1057                                 cycx_poke(&card->hw, addr + len1, d2, len2);
1058                 }
1059         }
1060 
1061         /* generate interruption, executing command */
1062         cycx_intr(&card->hw);
1063 
1064         /* wait till card->mbox == 0 */
1065         do {
1066                 err = cycx_exec(card->mbox);
1067         } while (retry-- && err);
1068 
1069         spin_unlock_irqrestore(&card->u.x.lock, flags);
1070 
1071         return err;
1072 }
1073 
1074 /* Configure adapter. */
1075 static int cycx_x25_configure(struct cycx_device *card,
1076                               struct cycx_x25_config *conf)
1077 {
1078         struct {
1079                 u16 nlinks;
1080                 struct cycx_x25_config conf[2];
1081         } x25_cmd_conf;
1082 
1083         memset(&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1084         x25_cmd_conf.nlinks = 2;
1085         x25_cmd_conf.conf[0] = *conf;
1086         /* FIXME: we need to find a way in the wanrouter framework
1087                   to configure the second link, for now lets use it
1088                   with the same config from the first link, fixing
1089                   the interface type to RS232, the speed in 38400 and
1090                   the clock to external */
1091         x25_cmd_conf.conf[1] = *conf;
1092         x25_cmd_conf.conf[1].link = 1;
1093         x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1094         x25_cmd_conf.conf[1].clock = 8;
1095         x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1096 
1097         cycx_x25_dump_config(&x25_cmd_conf.conf[0]);
1098         cycx_x25_dump_config(&x25_cmd_conf.conf[1]);
1099 
1100         return x25_exec(card, X25_CONFIG, 0,
1101                         &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1102 }
1103 
1104 /* Get protocol statistics. */
1105 static int cycx_x25_get_stats(struct cycx_device *card)
1106 {
1107         /* the firmware expects 20 in the size field!!!
1108            thanks to Daniela */
1109         int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1110 
1111         if (err)
1112                 return err;
1113 
1114         interruptible_sleep_on(&card->wait_stats);
1115 
1116         if (signal_pending(current))
1117                 return -EINTR;
1118 
1119         card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1120         card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1121         card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1122         card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1123         card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1124         card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1125         card->wandev.stats.rx_dropped = 0; /* not available from fw */
1126         card->wandev.stats.rx_errors = 0; /* not available from fw */
1127         card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1128         card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1129         card->wandev.stats.tx_dropped = 0; /* not available from fw */
1130         card->wandev.stats.collisions = 0; /* not available from fw */
1131         card->wandev.stats.tx_errors = 0; /* not available from fw */
1132 
1133         cycx_x25_dump_devs(&card->wandev);
1134 
1135         return 0;
1136 }
1137 
1138 /* return the number of nibbles */
1139 static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1140 {
1141         int i = 0;
1142 
1143         if (*nibble && *s) {
1144                 d[i] |= *s++ - '';
1145                 *nibble = 0;
1146                 ++i;
1147         }
1148 
1149         while (*s) {
1150                 d[i] = (*s - '') << 4;
1151                 if (*(s + 1))
1152                         d[i] |= *(s + 1) - '';
1153                 else {
1154                         *nibble = 1;
1155                         break;
1156                 }
1157                 ++i;
1158                 s += 2;
1159         }
1160 
1161         return i;
1162 }
1163 
1164 static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1165 {
1166         if (nibble) {
1167                 *d++ = '' + (*s++ & 0x0F);
1168                 --len;
1169         }
1170 
1171         while (len) {
1172                 *d++ = '' + (*s >> 4);
1173 
1174                 if (--len) {
1175                         *d++ = '' + (*s & 0x0F);
1176                         --len;
1177                 } else break;
1178 
1179                 ++s;
1180         }
1181 
1182         *d = '\0';
1183 }
1184 
1185 /* Place X.25 call. */
1186 static int x25_place_call(struct cycx_device *card,
1187                           struct cycx_x25_channel *chan)
1188 {
1189         int err = 0,
1190             len;
1191         char d[64],
1192              nibble = 0,
1193              mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1194              remotelen = strlen(chan->addr);
1195         u8 key;
1196 
1197         if (card->u.x.connection_keys == ~0U) {
1198                 printk(KERN_INFO "%s: too many simultaneous connection "
1199                                  "requests!\n", card->devname);
1200                 return -EAGAIN;
1201         }
1202 
1203         key = ffz(card->u.x.connection_keys);
1204         set_bit(key, (void*)&card->u.x.connection_keys);
1205         ++key;
1206         dprintk(1, KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1207         memset(d, 0, sizeof(d));
1208         d[1] = key; /* user key */
1209         d[2] = 0x10;
1210         d[4] = 0x0B;
1211 
1212         len = byte_to_nibble(chan->addr, d + 6, &nibble);
1213 
1214         if (chan->local_addr)
1215                 len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
1216 
1217         if (nibble)
1218                 ++len;
1219 
1220         d[5] = mylen << 4 | remotelen;
1221         d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
1222 
1223         if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1224                             &d, 7 + len + 1, NULL, 0)) != 0)
1225                 clear_bit(--key, (void*)&card->u.x.connection_keys);
1226         else
1227                 chan->lcn = -key;
1228 
1229         return err;
1230 }
1231 
1232 /* Place X.25 CONNECT RESPONSE. */
1233 static int cycx_x25_connect_response(struct cycx_device *card,
1234                                      struct cycx_x25_channel *chan)
1235 {
1236         u8 d[8];
1237 
1238         memset(d, 0, sizeof(d));
1239         d[0] = d[3] = chan->lcn;
1240         d[2] = 0x10;
1241         d[4] = 0x0F;
1242         d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
1243 
1244         return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
1245 }
1246 
1247 /* Place X.25 DISCONNECT RESPONSE.  */
1248 static int cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
1249                                         u8 lcn)
1250 {
1251         char d[5];
1252 
1253         memset(d, 0, sizeof(d));
1254         d[0] = d[3] = lcn;
1255         d[2] = 0x10;
1256         d[4] = 0x17;
1257 
1258         return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
1259 }
1260 
1261 /* Clear X.25 call.  */
1262 static int x25_clear_call(struct cycx_device *card, u8 link, u8 lcn, u8 cause,
1263                           u8 diagn)
1264 {
1265         u8 d[7];
1266 
1267         memset(d, 0, sizeof(d));
1268         d[0] = d[3] = lcn;
1269         d[2] = 0x10;
1270         d[4] = 0x13;
1271         d[5] = cause;
1272         d[6] = diagn;
1273 
1274         return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
1275 }
1276 
1277 /* Send X.25 data packet. */
1278 static int cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
1279                          int len, void *buf)
1280 {
1281         u8 d[] = "?\xFF\x10??";
1282 
1283         d[0] = d[3] = lcn;
1284         d[4] = bitm;
1285 
1286         return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
1287 }
1288 
1289 /* Miscellaneous */
1290 /* Find network device by its channel number.  */
1291 static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
1292                                                   s16 lcn)
1293 {
1294         struct net_device *dev = wandev->dev;
1295         struct cycx_x25_channel *chan;
1296 
1297         while (dev) {
1298                 chan = (struct cycx_x25_channel*)dev->priv;
1299 
1300                 if (chan->lcn == lcn)
1301                         break;
1302                 dev = chan->slave;
1303         }
1304         return dev;
1305 }
1306 
1307 /* Find network device by its remote dte address. */
1308 static struct net_device *
1309         cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte)
1310 {
1311         struct net_device *dev = wandev->dev;
1312         struct cycx_x25_channel *chan;
1313 
1314         while (dev) {
1315                 chan = (struct cycx_x25_channel*)dev->priv;
1316 
1317                 if (!strcmp(chan->addr, dte))
1318                         break;
1319                 dev = chan->slave;
1320         }
1321         return dev;
1322 }
1323 
1324 /* Initiate connection on the logical channel.
1325  * o for PVC we just get channel configuration
1326  * o for SVCs place an X.25 call
1327  *
1328  * Return:      0       connected
1329  *              >0      connection in progress
1330  *              <0      failure */
1331 static int cycx_x25_chan_connect(struct net_device *dev)
1332 {
1333         struct cycx_x25_channel *chan = dev->priv;
1334         struct cycx_device *card = chan->card;
1335 
1336         if (chan->svc) {
1337                 if (!chan->addr[0])
1338                         return -EINVAL; /* no destination address */
1339 
1340                 dprintk(1, KERN_INFO "%s: placing X.25 call to %s...\n",
1341                                   card->devname, chan->addr);
1342 
1343                 if (x25_place_call(card, chan))
1344                         return -EIO;
1345 
1346                 cycx_x25_set_chan_state(dev, WAN_CONNECTING);
1347                 return 1;
1348         } else
1349                 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
1350 
1351         return 0;
1352 }
1353 
1354 /* Disconnect logical channel.
1355  * o if SVC then clear X.25 call */
1356 static void cycx_x25_chan_disconnect(struct net_device *dev)
1357 {
1358         struct cycx_x25_channel *chan = dev->priv;
1359 
1360         if (chan->svc) {
1361                 x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1362                 cycx_x25_set_chan_state(dev, WAN_DISCONNECTING);
1363         } else
1364                 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
1365 }
1366 
1367 /* Called by kernel timer */
1368 static void cycx_x25_chan_timer(unsigned long d)
1369 {
1370         struct net_device *dev = (struct net_device *)d;
1371         struct cycx_x25_channel *chan = dev->priv;
1372 
1373         if (chan->state == WAN_CONNECTED)
1374                 cycx_x25_chan_disconnect(dev);
1375         else
1376                 printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
1377                                 chan->card->devname, __FUNCTION__, dev->name);
1378 }
1379 
1380 /* Set logical channel state. */
1381 static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
1382 {
1383         struct cycx_x25_channel *chan = dev->priv;
1384         struct cycx_device *card = chan->card;
1385         unsigned long flags;
1386         char *string_state = NULL;
1387 
1388         spin_lock_irqsave(&card->lock, flags);
1389 
1390         if (chan->state != state) {
1391                 if (chan->svc && chan->state == WAN_CONNECTED)
1392                         del_timer(&chan->timer);
1393 
1394                 switch (state) {
1395                 case WAN_CONNECTED:
1396                         string_state = "connected!";
1397                         *(u16*)dev->dev_addr = htons(chan->lcn);
1398                         netif_wake_queue(dev);
1399                         reset_timer(dev);
1400 
1401                         if (chan->protocol == ETH_P_X25)
1402                                 cycx_x25_chan_send_event(dev, 1);
1403 
1404                         break;
1405                 case WAN_CONNECTING:
1406                         string_state = "connecting...";
1407                         break;
1408                 case WAN_DISCONNECTING:
1409                         string_state = "disconnecting...";
1410                         break;
1411                 case WAN_DISCONNECTED:
1412                         string_state = "disconnected!";
1413 
1414                         if (chan->svc) {
1415                                 *(unsigned short*)dev->dev_addr = 0;
1416                                 chan->lcn = 0;
1417                         }
1418 
1419                         if (chan->protocol == ETH_P_X25)
1420                                 cycx_x25_chan_send_event(dev, 2);
1421 
1422                         netif_wake_queue(dev);
1423                         break;
1424                 }
1425 
1426                 printk(KERN_INFO "%s: interface %s %s\n", card->devname,
1427                                   dev->name, string_state);
1428                 chan->state = state;
1429         }
1430 
1431         spin_unlock_irqrestore(&card->lock, flags);
1432 }
1433 
1434 /* Send packet on a logical channel.
1435  *      When this function is called, tx_skb field of the channel data space
1436  *      points to the transmit socket buffer.  When transmission is complete,
1437  *      release socket buffer and reset 'tbusy' flag.
1438  *
1439  * Return:      0       - transmission complete
1440  *              1       - busy
1441  *
1442  * Notes:
1443  * 1. If packet length is greater than MTU for this channel, we'll fragment
1444  *    the packet into 'complete sequence' using M-bit.
1445  * 2. When transmission is complete, an event notification should be issued
1446  *    to the router.  */
1447 static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
1448 {
1449         struct cycx_x25_channel *chan = dev->priv;
1450         struct cycx_device *card = chan->card;
1451         int bitm = 0;           /* final packet */
1452         unsigned len = skb->len;
1453 
1454         if (skb->len > card->wandev.mtu) {
1455                 len = card->wandev.mtu;
1456                 bitm = 0x10;            /* set M-bit (more data) */
1457         }
1458 
1459         if (cycx_x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1460                 return 1;
1461 
1462         if (bitm) {
1463                 skb_pull(skb, len);
1464                 return 1;
1465         }
1466 
1467         ++chan->ifstats.tx_packets;
1468         chan->ifstats.tx_bytes += len;
1469 
1470         return 0;
1471 }
1472 
1473 /* Send event (connection, disconnection, etc) to X.25 socket layer */
1474 
1475 static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
1476 {
1477         struct sk_buff *skb;
1478         unsigned char *ptr;
1479 
1480         if ((skb = dev_alloc_skb(1)) == NULL) {
1481                 printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
1482                 return;
1483         }
1484 
1485         ptr  = skb_put(skb, 1);
1486         *ptr = event;
1487 
1488         skb->protocol = x25_type_trans(skb, dev);
1489         netif_rx(skb);
1490         dev->last_rx = jiffies;         /* timestamp */
1491 }
1492 
1493 /* Convert line speed in bps to a number used by cyclom 2x code. */
1494 static u8 bps_to_speed_code(u32 bps)
1495 {
1496         u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1497 
1498              if (bps >= 512000) number = 8;
1499         else if (bps >= 256000) number = 7;
1500         else if (bps >= 64000)  number = 6;
1501         else if (bps >= 38400)  number = 5;
1502         else if (bps >= 19200)  number = 4;
1503         else if (bps >= 9600)   number = 3;
1504         else if (bps >= 4800)   number = 2;
1505         else if (bps >= 2400)   number = 1;
1506 
1507         return number;
1508 }
1509 
1510 /* log base 2 */
1511 static u8 cycx_log2(u32 n)
1512 {
1513         u8 log = 0;
1514 
1515         if (!n)
1516                 return 0;
1517 
1518         while (n > 1) {
1519                 n >>= 1;
1520                 ++log;
1521         }
1522 
1523         return log;
1524 }
1525 
1526 /* Convert decimal string to unsigned integer.
1527  * If len != 0 then only 'len' characters of the string are converted. */
1528 static unsigned dec_to_uint(u8 *str, int len)
1529 {
1530         unsigned val = 0;
1531 
1532         if (!len)
1533                 len = strlen(str);
1534 
1535         for (; len && isdigit(*str); ++str, --len)
1536                 val = (val * 10) + (*str - (unsigned) '');
1537 
1538         return val;
1539 }
1540 
1541 static void reset_timer(struct net_device *dev)
1542 {
1543         struct cycx_x25_channel *chan = dev->priv;
1544 
1545         if (chan->svc)
1546                 mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
1547 }
1548 #ifdef CYCLOMX_X25_DEBUG
1549 static void cycx_x25_dump_config(struct cycx_x25_config *conf)
1550 {
1551         printk(KERN_INFO "X.25 configuration\n");
1552         printk(KERN_INFO "-----------------\n");
1553         printk(KERN_INFO "link number=%d\n", conf->link);
1554         printk(KERN_INFO "line speed=%d\n", conf->speed);
1555         printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1556         printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1557         printk(KERN_INFO "level 2 window=%d\n", conf->n2win);
1558         printk(KERN_INFO "level 3 window=%d\n", conf->n3win);
1559         printk(KERN_INFO "# logical channels=%d\n", conf->nvc);
1560         printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1561         printk(KERN_INFO "my address=%d\n", conf->locaddr);
1562         printk(KERN_INFO "remote address=%d\n", conf->remaddr);
1563         printk(KERN_INFO "t1=%d seconds\n", conf->t1);
1564         printk(KERN_INFO "t2=%d seconds\n", conf->t2);
1565         printk(KERN_INFO "t21=%d seconds\n", conf->t21);
1566         printk(KERN_INFO "# PVCs=%d\n", conf->npvc);
1567         printk(KERN_INFO "t23=%d seconds\n", conf->t23);
1568         printk(KERN_INFO "flags=0x%x\n", conf->flags);
1569 }
1570 
1571 static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
1572 {
1573         printk(KERN_INFO "X.25 statistics\n");
1574         printk(KERN_INFO "--------------\n");
1575         printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1576         printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1577         printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1578         printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1579         printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1580         printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1581         printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1582         printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1583         printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1584         printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1585 }
1586 
1587 static void cycx_x25_dump_devs(struct wan_device *wandev)
1588 {
1589         struct net_device *dev = wandev->dev;
1590 
1591         printk(KERN_INFO "X.25 dev states\n");
1592         printk(KERN_INFO "name: addr:           txoff:  protocol:\n");
1593         printk(KERN_INFO "---------------------------------------\n");
1594 
1595         while(dev) {
1596                 struct cycx_x25_channel *chan = dev->priv;
1597 
1598                 printk(KERN_INFO "%-5.5s %-15.15s   %d     ETH_P_%s\n",
1599                                  chan->name, chan->addr, netif_queue_stopped(dev),
1600                                  chan->protocol == ETH_P_IP ? "IP" : "X25");
1601                 dev = chan->slave;
1602         }
1603 }
1604 
1605 #endif /* CYCLOMX_X25_DEBUG */
1606 /* End */
1607 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.