Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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