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