OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [wan/] [cycx_x25.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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
#ifdef CYCLOMX_X25_DEBUG
203
static void hex_dump(char *msg, unsigned char *p, int len);
204
static void cycx_x25_dump_config(struct cycx_x25_config *conf);
205
static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
206
static void cycx_x25_dump_devs(struct wan_device *wandev);
207
#else
208
#define hex_dump(msg, p, len)
209
#define cycx_x25_dump_config(conf)
210
#define cycx_x25_dump_stats(stats)
211
#define cycx_x25_dump_devs(wandev)
212
#endif
213
/* Public Functions */
214
 
215
/* X.25 Protocol Initialization routine.
216
 *
217
 * This routine is called by the main Cyclom 2X module during setup.  At this
218
 * point adapter is completely initialized and X.25 firmware is running.
219
 *  o configure adapter
220
 *  o initialize protocol-specific fields of the adapter data space.
221
 *
222
 * Return:      0        o.k.
223
 *              < 0     failure.  */
224
int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
225
{
226
        struct cycx_x25_config cfg;
227
 
228
        /* Verify configuration ID */
229
        if (conf->config_id != WANCONFIG_X25) {
230
                printk(KERN_INFO "%s: invalid configuration ID %u!\n",
231
                                 card->devname, conf->config_id);
232
                return -EINVAL;
233
        }
234
 
235
        /* Initialize protocol-specific fields */
236
        card->mbox  = card->hw.dpmbase + X25_MBOX_OFFS;
237
        card->u.x.connection_keys = 0;
238
        spin_lock_init(&card->u.x.lock);
239
 
240
        /* Configure adapter. Here we set reasonable defaults, then parse
241
         * device configuration structure and set configuration options.
242
         * Most configuration options are verified and corrected (if
243
         * necessary) since we can't rely on the adapter to do so and don't
244
         * want it to fail either. */
245
        memset(&cfg, 0, sizeof(cfg));
246
        cfg.link = 0;
247
        cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
248
        cfg.speed = bps_to_speed_code(conf->bps);
249
        cfg.n3win = 7;
250
        cfg.n2win = 2;
251
        cfg.n2 = 5;
252
        cfg.nvc = 1;
253
        cfg.npvc = 1;
254
        cfg.flags = 0x02; /* default = V35 */
255
        cfg.t1 = 10;   /* line carrier timeout */
256
        cfg.t2 = 29;   /* tx timeout */
257
        cfg.t21 = 180; /* CALL timeout */
258
        cfg.t23 = 180; /* CLEAR timeout */
259
 
260
        /* adjust MTU */
261
        if (!conf->mtu || conf->mtu >= 512)
262
                card->wandev.mtu = 512;
263
        else if (conf->mtu >= 256)
264
                card->wandev.mtu = 256;
265
        else if (conf->mtu >= 128)
266
                card->wandev.mtu = 128;
267
        else
268
                card->wandev.mtu = 64;
269
 
270
        cfg.pktlen = cycx_log2(card->wandev.mtu);
271
 
272
        if (conf->station == WANOPT_DTE) {
273
                cfg.locaddr = 3; /* DTE */
274
                cfg.remaddr = 1; /* DCE */
275
        } else {
276
                cfg.locaddr = 1; /* DCE */
277
                cfg.remaddr = 3; /* DTE */
278
        }
279
 
280
        if (conf->interface == WANOPT_RS232)
281
                cfg.flags = 0;      /* FIXME just reset the 2nd bit */
282
 
283
        if (conf->u.x25.hi_pvc) {
284
                card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
285
                card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
286
        }
287
 
288
        if (conf->u.x25.hi_svc) {
289
                card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
290
                card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
291
        }
292
 
293
        if (card->u.x.lo_pvc == 255)
294
                cfg.npvc = 0;
295
        else
296
                cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
297
 
298
        cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
299
 
300
        if (conf->u.x25.hdlc_window)
301
                cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
302
 
303
        if (conf->u.x25.pkt_window)
304
                cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
305
 
306
        if (conf->u.x25.t1)
307
                cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
308
 
309
        if (conf->u.x25.t2)
310
                cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
311
 
312
        if (conf->u.x25.t11_t21)
313
                cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
314
 
315
        if (conf->u.x25.t13_t23)
316
                cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
317
 
318
        if (conf->u.x25.n2)
319
                cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
320
 
321
        /* initialize adapter */
322
        if (cycx_x25_configure(card, &cfg))
323
                return -EIO;
324
 
325
        /* Initialize protocol-specific fields of adapter data space */
326
        card->wandev.bps        = conf->bps;
327
        card->wandev.interface  = conf->interface;
328
        card->wandev.clocking   = conf->clocking;
329
        card->wandev.station    = conf->station;
330
        card->isr               = cycx_x25_irq_handler;
331
        card->exec              = NULL;
332
        card->wandev.update     = cycx_wan_update;
333
        card->wandev.new_if     = cycx_wan_new_if;
334
        card->wandev.del_if     = cycx_wan_del_if;
335
        card->wandev.state      = WAN_DISCONNECTED;
336
 
337
        return 0;
338
}
339
 
340
/* WAN Device Driver Entry Points */
341
/* Update device status & statistics. */
342
static int cycx_wan_update(struct wan_device *wandev)
343
{
344
        /* sanity checks */
345
        if (!wandev || !wandev->private)
346
                return -EFAULT;
347
 
348
        if (wandev->state == WAN_UNCONFIGURED)
349
                return -ENODEV;
350
 
351
        cycx_x25_get_stats(wandev->private);
352
 
353
        return 0;
354
}
355
 
356
/* Create new logical channel.
357
 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
358
 * handled.
359
 * o parse media- and hardware-specific configuration
360
 * o make sure that a new channel can be created
361
 * o allocate resources, if necessary
362
 * o prepare network device structure for registration.
363
 *
364
 * Return:      0        o.k.
365
 *              < 0     failure (channel will not be created) */
366
static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
367
                           wanif_conf_t *conf)
368
{
369
        struct cycx_device *card = wandev->private;
370
        struct cycx_x25_channel *chan;
371
        int err = 0;
372
 
373
        if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
374
                printk(KERN_INFO "%s: invalid interface name!\n",
375
                       card->devname);
376
                return -EINVAL;
377
        }
378
 
379
        /* allocate and initialize private data */
380
        chan = kzalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL);
381
        if (!chan)
382
                return -ENOMEM;
383
 
384
        strcpy(chan->name, conf->name);
385
        chan->card = card;
386
        chan->link = conf->port;
387
        chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
388
        chan->rx_skb = NULL;
389
        /* only used in svc connected thru crossover cable */
390
        chan->local_addr = NULL;
391
 
392
        if (conf->addr[0] == '@') {      /* SVC */
393
                int len = strlen(conf->local_addr);
394
 
395
                if (len) {
396
                        if (len > WAN_ADDRESS_SZ) {
397
                                printk(KERN_ERR "%s: %s local addr too long!\n",
398
                                                wandev->name, chan->name);
399
                                kfree(chan);
400
                                return -EINVAL;
401
                        } else {
402
                                chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
403
 
404
                                if (!chan->local_addr) {
405
                                        kfree(chan);
406
                                        return -ENOMEM;
407
                                }
408
                        }
409
 
410
                        strncpy(chan->local_addr, conf->local_addr,
411
                                WAN_ADDRESS_SZ);
412
                }
413
 
414
                chan->svc = 1;
415
                strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
416
                init_timer(&chan->timer);
417
                chan->timer.function    = cycx_x25_chan_timer;
418
                chan->timer.data        = (unsigned long)dev;
419
 
420
                /* Set channel timeouts (default if not specified) */
421
                chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
422
        } else if (isdigit(conf->addr[0])) {     /* PVC */
423
                s16 lcn = dec_to_uint(conf->addr, 0);
424
 
425
                if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
426
                        chan->lcn = lcn;
427
                else {
428
                        printk(KERN_ERR
429
                                "%s: PVC %u is out of range on interface %s!\n",
430
                                wandev->name, lcn, chan->name);
431
                        err = -EINVAL;
432
                }
433
        } else {
434
                printk(KERN_ERR "%s: invalid media address on interface %s!\n",
435
                                wandev->name, chan->name);
436
                err = -EINVAL;
437
        }
438
 
439
        if (err) {
440
                kfree(chan->local_addr);
441
                kfree(chan);
442
                return err;
443
        }
444
 
445
        /* prepare network device data space for registration */
446
        strcpy(dev->name, chan->name);
447
        dev->init = cycx_netdevice_init;
448
        dev->priv = chan;
449
 
450
        return 0;
451
}
452
 
453
/* Delete logical channel. */
454
static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
455
{
456
        if (dev->priv) {
457
                struct cycx_x25_channel *chan = dev->priv;
458
 
459
                if (chan->svc) {
460
                        kfree(chan->local_addr);
461
                        if (chan->state == WAN_CONNECTED)
462
                                del_timer(&chan->timer);
463
                }
464
 
465
                kfree(chan);
466
                dev->priv = NULL;
467
        }
468
 
469
        return 0;
470
}
471
 
472
 
473
/* Network Device Interface */
474
 
475
static const struct header_ops cycx_header_ops = {
476
        .create = cycx_netdevice_hard_header,
477
        .rebuild = cycx_netdevice_rebuild_header,
478
};
479
 
480
/* Initialize Linux network interface.
481
 *
482
 * This routine is called only once for each interface, during Linux network
483
 * interface registration.  Returning anything but zero will fail interface
484
 * registration. */
485
static int cycx_netdevice_init(struct net_device *dev)
486
{
487
        struct cycx_x25_channel *chan = dev->priv;
488
        struct cycx_device *card = chan->card;
489
        struct wan_device *wandev = &card->wandev;
490
 
491
        /* Initialize device driver entry points */
492
        dev->open               = cycx_netdevice_open;
493
        dev->stop               = cycx_netdevice_stop;
494
        dev->header_ops         = &cycx_header_ops;
495
 
496
        dev->hard_start_xmit    = cycx_netdevice_hard_start_xmit;
497
        dev->get_stats          = cycx_netdevice_get_stats;
498
 
499
        /* Initialize media-specific parameters */
500
        dev->mtu                = CYCX_X25_CHAN_MTU;
501
        dev->type               = ARPHRD_HWX25; /* ARP h/w type */
502
        dev->hard_header_len    = 0;             /* media header length */
503
        dev->addr_len           = 0;             /* hardware address length */
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 = dev->priv;
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 = dev->priv;
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 -EBUSY;
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 -EBUSY;
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 -EBUSY;
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 = dev->priv;
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 = dev->priv;
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
        dev->last_rx = jiffies;         /* timestamp */
847
}
848
 
849
/* Connect interrupt handler. */
850
static void cycx_x25_irq_connect(struct cycx_device *card,
851
                                 struct cycx_x25_cmd *cmd)
852
{
853
        struct wan_device *wandev = &card->wandev;
854
        struct net_device *dev = NULL;
855
        struct cycx_x25_channel *chan;
856
        u8 d[32],
857
           loc[24],
858
           rem[24];
859
        u8 lcn, sizeloc, sizerem;
860
 
861
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
862
        cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
863
        cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
864
 
865
        sizerem = sizeloc >> 4;
866
        sizeloc &= 0x0F;
867
 
868
        loc[0] = rem[0] = '\0';
869
 
870
        if (sizeloc)
871
                nibble_to_byte(d, loc, sizeloc, 0);
872
 
873
        if (sizerem)
874
                nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
875
 
876
        dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
877
                          __FUNCTION__, lcn, loc, rem);
878
 
879
        dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
880
        if (!dev) {
881
                /* Invalid channel, discard packet */
882
                printk(KERN_INFO "%s: connect not expected: remote %s!\n",
883
                                 card->devname, rem);
884
                return;
885
        }
886
 
887
        chan = dev->priv;
888
        chan->lcn = lcn;
889
        cycx_x25_connect_response(card, chan);
890
        cycx_x25_set_chan_state(dev, WAN_CONNECTED);
891
}
892
 
893
/* Connect confirm interrupt handler. */
894
static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
895
                                         struct cycx_x25_cmd *cmd)
896
{
897
        struct wan_device *wandev = &card->wandev;
898
        struct net_device *dev;
899
        struct cycx_x25_channel *chan;
900
        u8 lcn, key;
901
 
902
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
903
        cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
904
        dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
905
                          card->devname, __FUNCTION__, lcn, key);
906
 
907
        dev = cycx_x25_get_dev_by_lcn(wandev, -key);
908
        if (!dev) {
909
                /* Invalid channel, discard packet */
910
                clear_bit(--key, (void*)&card->u.x.connection_keys);
911
                printk(KERN_INFO "%s: connect confirm not expected: lcn %d, "
912
                                 "key=%d!\n", card->devname, lcn, key);
913
                return;
914
        }
915
 
916
        clear_bit(--key, (void*)&card->u.x.connection_keys);
917
        chan = dev->priv;
918
        chan->lcn = lcn;
919
        cycx_x25_set_chan_state(dev, WAN_CONNECTED);
920
}
921
 
922
/* Disconnect confirm interrupt handler. */
923
static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
924
                                            struct cycx_x25_cmd *cmd)
925
{
926
        struct wan_device *wandev = &card->wandev;
927
        struct net_device *dev;
928
        u8 lcn;
929
 
930
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
931
        dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
932
                          card->devname, __FUNCTION__, lcn);
933
        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
934
        if (!dev) {
935
                /* Invalid channel, discard packet */
936
                printk(KERN_INFO "%s:disconnect confirm not expected!:lcn %d\n",
937
                                 card->devname, lcn);
938
                return;
939
        }
940
 
941
        cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
942
}
943
 
944
/* disconnect interrupt handler. */
945
static void cycx_x25_irq_disconnect(struct cycx_device *card,
946
                                    struct cycx_x25_cmd *cmd)
947
{
948
        struct wan_device *wandev = &card->wandev;
949
        struct net_device *dev;
950
        u8 lcn;
951
 
952
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
953
        dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn);
954
 
955
        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
956
        if (dev) {
957
                struct cycx_x25_channel *chan = dev->priv;
958
 
959
                cycx_x25_disconnect_response(card, chan->link, lcn);
960
                cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
961
        } else
962
                cycx_x25_disconnect_response(card, 0, lcn);
963
}
964
 
965
/* LOG interrupt handler. */
966
static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd)
967
{
968
#if CYCLOMX_X25_DEBUG
969
        char bf[20];
970
        u16 size, toread, link, msg_code;
971
        u8 code, routine;
972
 
973
        cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
974
        cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
975
        cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
976
        /* at most 20 bytes are available... thanks to Daniela :) */
977
        toread = size < 20 ? size : 20;
978
        cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
979
        cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
980
        cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
981
 
982
        printk(KERN_INFO "cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n");
983
        printk(KERN_INFO "cmd->buf=0x%X\n", cmd->buf);
984
        printk(KERN_INFO "Log message code=0x%X\n", msg_code);
985
        printk(KERN_INFO "Link=%d\n", link);
986
        printk(KERN_INFO "log code=0x%X\n", code);
987
        printk(KERN_INFO "log routine=0x%X\n", routine);
988
        printk(KERN_INFO "Message size=%d\n", size);
989
        hex_dump("Message", bf, toread);
990
#endif
991
}
992
 
993
/* STATISTIC interrupt handler. */
994
static void cycx_x25_irq_stat(struct cycx_device *card,
995
                              struct cycx_x25_cmd *cmd)
996
{
997
        cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
998
                  sizeof(card->u.x.stats));
999
        hex_dump("cycx_x25_irq_stat", (unsigned char*)&card->u.x.stats,
1000
                 sizeof(card->u.x.stats));
1001
        cycx_x25_dump_stats(&card->u.x.stats);
1002
        wake_up_interruptible(&card->wait_stats);
1003
}
1004
 
1005
/* Spurious interrupt handler.
1006
 * o print a warning
1007
 * If number of spurious interrupts exceeded some limit, then ??? */
1008
static void cycx_x25_irq_spurious(struct cycx_device *card,
1009
                                  struct cycx_x25_cmd *cmd)
1010
{
1011
        printk(KERN_INFO "%s: spurious interrupt (0x%X)!\n",
1012
                         card->devname, cmd->command);
1013
}
1014
#ifdef CYCLOMX_X25_DEBUG
1015
static void hex_dump(char *msg, unsigned char *p, int len)
1016
{
1017
        unsigned char hex[1024],
1018
                * phex = hex;
1019
 
1020
        if (len >= (sizeof(hex) / 2))
1021
                len = (sizeof(hex) / 2) - 1;
1022
 
1023
        while (len--) {
1024
                sprintf(phex, "%02x", *p++);
1025
                phex += 2;
1026
        }
1027
 
1028
        printk(KERN_INFO "%s: %s\n", msg, hex);
1029
}
1030
#endif
1031
 
1032
/* Cyclom 2X Firmware-Specific Functions */
1033
/* Exec X.25 command. */
1034
static int x25_exec(struct cycx_device *card, int command, int link,
1035
                    void *d1, int len1, void *d2, int len2)
1036
{
1037
        struct cycx_x25_cmd c;
1038
        unsigned long flags;
1039
        u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
1040
        u8 retry = CYCX_X25_MAX_CMD_RETRY;
1041
        int err = 0;
1042
 
1043
        c.command = command;
1044
        c.link = link;
1045
        c.len = len1 + len2;
1046
 
1047
        spin_lock_irqsave(&card->u.x.lock, flags);
1048
 
1049
        /* write command */
1050
        cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
1051
 
1052
        /* write X.25 data */
1053
        if (d1) {
1054
                cycx_poke(&card->hw, addr, d1, len1);
1055
 
1056
                if (d2) {
1057
                        if (len2 > 254) {
1058
                                u32 addr1 = 0xA00 + 0x400 * link;
1059
 
1060
                                cycx_poke(&card->hw, addr + len1, d2, 249);
1061
                                cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
1062
                                          len2 - 249);
1063
                        } else
1064
                                cycx_poke(&card->hw, addr + len1, d2, len2);
1065
                }
1066
        }
1067
 
1068
        /* generate interruption, executing command */
1069
        cycx_intr(&card->hw);
1070
 
1071
        /* wait till card->mbox == 0 */
1072
        do {
1073
                err = cycx_exec(card->mbox);
1074
        } while (retry-- && err);
1075
 
1076
        spin_unlock_irqrestore(&card->u.x.lock, flags);
1077
 
1078
        return err;
1079
}
1080
 
1081
/* Configure adapter. */
1082
static int cycx_x25_configure(struct cycx_device *card,
1083
                              struct cycx_x25_config *conf)
1084
{
1085
        struct {
1086
                u16 nlinks;
1087
                struct cycx_x25_config conf[2];
1088
        } x25_cmd_conf;
1089
 
1090
        memset(&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1091
        x25_cmd_conf.nlinks = 2;
1092
        x25_cmd_conf.conf[0] = *conf;
1093
        /* FIXME: we need to find a way in the wanrouter framework
1094
                  to configure the second link, for now lets use it
1095
                  with the same config from the first link, fixing
1096
                  the interface type to RS232, the speed in 38400 and
1097
                  the clock to external */
1098
        x25_cmd_conf.conf[1] = *conf;
1099
        x25_cmd_conf.conf[1].link = 1;
1100
        x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1101
        x25_cmd_conf.conf[1].clock = 8;
1102
        x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1103
 
1104
        cycx_x25_dump_config(&x25_cmd_conf.conf[0]);
1105
        cycx_x25_dump_config(&x25_cmd_conf.conf[1]);
1106
 
1107
        return x25_exec(card, X25_CONFIG, 0,
1108
                        &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1109
}
1110
 
1111
/* Get protocol statistics. */
1112
static int cycx_x25_get_stats(struct cycx_device *card)
1113
{
1114
        /* the firmware expects 20 in the size field!!!
1115
           thanks to Daniela */
1116
        int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1117
 
1118
        if (err)
1119
                return err;
1120
 
1121
        interruptible_sleep_on(&card->wait_stats);
1122
 
1123
        if (signal_pending(current))
1124
                return -EINTR;
1125
 
1126
        card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1127
        card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1128
        card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1129
        card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1130
        card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1131
        card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1132
        card->wandev.stats.rx_dropped = 0; /* not available from fw */
1133
        card->wandev.stats.rx_errors = 0; /* not available from fw */
1134
        card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1135
        card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1136
        card->wandev.stats.tx_dropped = 0; /* not available from fw */
1137
        card->wandev.stats.collisions = 0; /* not available from fw */
1138
        card->wandev.stats.tx_errors = 0; /* not available from fw */
1139
 
1140
        cycx_x25_dump_devs(&card->wandev);
1141
 
1142
        return 0;
1143
}
1144
 
1145
/* return the number of nibbles */
1146
static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1147
{
1148
        int i = 0;
1149
 
1150
        if (*nibble && *s) {
1151
                d[i] |= *s++ - '0';
1152
                *nibble = 0;
1153
                ++i;
1154
        }
1155
 
1156
        while (*s) {
1157
                d[i] = (*s - '0') << 4;
1158
                if (*(s + 1))
1159
                        d[i] |= *(s + 1) - '0';
1160
                else {
1161
                        *nibble = 1;
1162
                        break;
1163
                }
1164
                ++i;
1165
                s += 2;
1166
        }
1167
 
1168
        return i;
1169
}
1170
 
1171
static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1172
{
1173
        if (nibble) {
1174
                *d++ = '0' + (*s++ & 0x0F);
1175
                --len;
1176
        }
1177
 
1178
        while (len) {
1179
                *d++ = '0' + (*s >> 4);
1180
 
1181
                if (--len) {
1182
                        *d++ = '0' + (*s & 0x0F);
1183
                        --len;
1184
                } else break;
1185
 
1186
                ++s;
1187
        }
1188
 
1189
        *d = '\0';
1190
}
1191
 
1192
/* Place X.25 call. */
1193
static int x25_place_call(struct cycx_device *card,
1194
                          struct cycx_x25_channel *chan)
1195
{
1196
        int err = 0,
1197
            len;
1198
        char d[64],
1199
             nibble = 0,
1200
             mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1201
             remotelen = strlen(chan->addr);
1202
        u8 key;
1203
 
1204
        if (card->u.x.connection_keys == ~0U) {
1205
                printk(KERN_INFO "%s: too many simultaneous connection "
1206
                                 "requests!\n", card->devname);
1207
                return -EAGAIN;
1208
        }
1209
 
1210
        key = ffz(card->u.x.connection_keys);
1211
        set_bit(key, (void*)&card->u.x.connection_keys);
1212
        ++key;
1213
        dprintk(1, KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1214
        memset(d, 0, sizeof(d));
1215
        d[1] = key; /* user key */
1216
        d[2] = 0x10;
1217
        d[4] = 0x0B;
1218
 
1219
        len = byte_to_nibble(chan->addr, d + 6, &nibble);
1220
 
1221
        if (chan->local_addr)
1222
                len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
1223
 
1224
        if (nibble)
1225
                ++len;
1226
 
1227
        d[5] = mylen << 4 | remotelen;
1228
        d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
1229
 
1230
        if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1231
                            &d, 7 + len + 1, NULL, 0)) != 0)
1232
                clear_bit(--key, (void*)&card->u.x.connection_keys);
1233
        else
1234
                chan->lcn = -key;
1235
 
1236
        return err;
1237
}
1238
 
1239
/* Place X.25 CONNECT RESPONSE. */
1240
static int cycx_x25_connect_response(struct cycx_device *card,
1241
                                     struct cycx_x25_channel *chan)
1242
{
1243
        u8 d[8];
1244
 
1245
        memset(d, 0, sizeof(d));
1246
        d[0] = d[3] = chan->lcn;
1247
        d[2] = 0x10;
1248
        d[4] = 0x0F;
1249
        d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
1250
 
1251
        return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
1252
}
1253
 
1254
/* Place X.25 DISCONNECT RESPONSE.  */
1255
static int cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
1256
                                        u8 lcn)
1257
{
1258
        char d[5];
1259
 
1260
        memset(d, 0, sizeof(d));
1261
        d[0] = d[3] = lcn;
1262
        d[2] = 0x10;
1263
        d[4] = 0x17;
1264
 
1265
        return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
1266
}
1267
 
1268
/* Clear X.25 call.  */
1269
static int x25_clear_call(struct cycx_device *card, u8 link, u8 lcn, u8 cause,
1270
                          u8 diagn)
1271
{
1272
        u8 d[7];
1273
 
1274
        memset(d, 0, sizeof(d));
1275
        d[0] = d[3] = lcn;
1276
        d[2] = 0x10;
1277
        d[4] = 0x13;
1278
        d[5] = cause;
1279
        d[6] = diagn;
1280
 
1281
        return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
1282
}
1283
 
1284
/* Send X.25 data packet. */
1285
static int cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
1286
                         int len, void *buf)
1287
{
1288
        u8 d[] = "?\xFF\x10??";
1289
 
1290
        d[0] = d[3] = lcn;
1291
        d[4] = bitm;
1292
 
1293
        return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
1294
}
1295
 
1296
/* Miscellaneous */
1297
/* Find network device by its channel number.  */
1298
static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
1299
                                                  s16 lcn)
1300
{
1301
        struct net_device *dev = wandev->dev;
1302
        struct cycx_x25_channel *chan;
1303
 
1304
        while (dev) {
1305
                chan = (struct cycx_x25_channel*)dev->priv;
1306
 
1307
                if (chan->lcn == lcn)
1308
                        break;
1309
                dev = chan->slave;
1310
        }
1311
        return dev;
1312
}
1313
 
1314
/* Find network device by its remote dte address. */
1315
static struct net_device *
1316
        cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte)
1317
{
1318
        struct net_device *dev = wandev->dev;
1319
        struct cycx_x25_channel *chan;
1320
 
1321
        while (dev) {
1322
                chan = (struct cycx_x25_channel*)dev->priv;
1323
 
1324
                if (!strcmp(chan->addr, dte))
1325
                        break;
1326
                dev = chan->slave;
1327
        }
1328
        return dev;
1329
}
1330
 
1331
/* Initiate connection on the logical channel.
1332
 * o for PVC we just get channel configuration
1333
 * o for SVCs place an X.25 call
1334
 *
1335
 * Return:      0        connected
1336
 *              >0       connection in progress
1337
 *              <0       failure */
1338
static int cycx_x25_chan_connect(struct net_device *dev)
1339
{
1340
        struct cycx_x25_channel *chan = dev->priv;
1341
        struct cycx_device *card = chan->card;
1342
 
1343
        if (chan->svc) {
1344
                if (!chan->addr[0])
1345
                        return -EINVAL; /* no destination address */
1346
 
1347
                dprintk(1, KERN_INFO "%s: placing X.25 call to %s...\n",
1348
                                  card->devname, chan->addr);
1349
 
1350
                if (x25_place_call(card, chan))
1351
                        return -EIO;
1352
 
1353
                cycx_x25_set_chan_state(dev, WAN_CONNECTING);
1354
                return 1;
1355
        } else
1356
                cycx_x25_set_chan_state(dev, WAN_CONNECTED);
1357
 
1358
        return 0;
1359
}
1360
 
1361
/* Disconnect logical channel.
1362
 * o if SVC then clear X.25 call */
1363
static void cycx_x25_chan_disconnect(struct net_device *dev)
1364
{
1365
        struct cycx_x25_channel *chan = dev->priv;
1366
 
1367
        if (chan->svc) {
1368
                x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1369
                cycx_x25_set_chan_state(dev, WAN_DISCONNECTING);
1370
        } else
1371
                cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
1372
}
1373
 
1374
/* Called by kernel timer */
1375
static void cycx_x25_chan_timer(unsigned long d)
1376
{
1377
        struct net_device *dev = (struct net_device *)d;
1378
        struct cycx_x25_channel *chan = dev->priv;
1379
 
1380
        if (chan->state == WAN_CONNECTED)
1381
                cycx_x25_chan_disconnect(dev);
1382
        else
1383
                printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
1384
                                chan->card->devname, __FUNCTION__, dev->name);
1385
}
1386
 
1387
/* Set logical channel state. */
1388
static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
1389
{
1390
        struct cycx_x25_channel *chan = dev->priv;
1391
        struct cycx_device *card = chan->card;
1392
        unsigned long flags;
1393
        char *string_state = NULL;
1394
 
1395
        spin_lock_irqsave(&card->lock, flags);
1396
 
1397
        if (chan->state != state) {
1398
                if (chan->svc && chan->state == WAN_CONNECTED)
1399
                        del_timer(&chan->timer);
1400
 
1401
                switch (state) {
1402
                case WAN_CONNECTED:
1403
                        string_state = "connected!";
1404
                        *(__be16*)dev->dev_addr = htons(chan->lcn);
1405
                        netif_wake_queue(dev);
1406
                        reset_timer(dev);
1407
 
1408
                        if (chan->protocol == ETH_P_X25)
1409
                                cycx_x25_chan_send_event(dev, 1);
1410
 
1411
                        break;
1412
                case WAN_CONNECTING:
1413
                        string_state = "connecting...";
1414
                        break;
1415
                case WAN_DISCONNECTING:
1416
                        string_state = "disconnecting...";
1417
                        break;
1418
                case WAN_DISCONNECTED:
1419
                        string_state = "disconnected!";
1420
 
1421
                        if (chan->svc) {
1422
                                *(unsigned short*)dev->dev_addr = 0;
1423
                                chan->lcn = 0;
1424
                        }
1425
 
1426
                        if (chan->protocol == ETH_P_X25)
1427
                                cycx_x25_chan_send_event(dev, 2);
1428
 
1429
                        netif_wake_queue(dev);
1430
                        break;
1431
                }
1432
 
1433
                printk(KERN_INFO "%s: interface %s %s\n", card->devname,
1434
                                  dev->name, string_state);
1435
                chan->state = state;
1436
        }
1437
 
1438
        spin_unlock_irqrestore(&card->lock, flags);
1439
}
1440
 
1441
/* Send packet on a logical channel.
1442
 *      When this function is called, tx_skb field of the channel data space
1443
 *      points to the transmit socket buffer.  When transmission is complete,
1444
 *      release socket buffer and reset 'tbusy' flag.
1445
 *
1446
 * Return:      0        - transmission complete
1447
 *              1       - busy
1448
 *
1449
 * Notes:
1450
 * 1. If packet length is greater than MTU for this channel, we'll fragment
1451
 *    the packet into 'complete sequence' using M-bit.
1452
 * 2. When transmission is complete, an event notification should be issued
1453
 *    to the router.  */
1454
static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
1455
{
1456
        struct cycx_x25_channel *chan = dev->priv;
1457
        struct cycx_device *card = chan->card;
1458
        int bitm = 0;            /* final packet */
1459
        unsigned len = skb->len;
1460
 
1461
        if (skb->len > card->wandev.mtu) {
1462
                len = card->wandev.mtu;
1463
                bitm = 0x10;            /* set M-bit (more data) */
1464
        }
1465
 
1466
        if (cycx_x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1467
                return 1;
1468
 
1469
        if (bitm) {
1470
                skb_pull(skb, len);
1471
                return 1;
1472
        }
1473
 
1474
        ++chan->ifstats.tx_packets;
1475
        chan->ifstats.tx_bytes += len;
1476
 
1477
        return 0;
1478
}
1479
 
1480
/* Send event (connection, disconnection, etc) to X.25 socket layer */
1481
 
1482
static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
1483
{
1484
        struct sk_buff *skb;
1485
        unsigned char *ptr;
1486
 
1487
        if ((skb = dev_alloc_skb(1)) == NULL) {
1488
                printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
1489
                return;
1490
        }
1491
 
1492
        ptr  = skb_put(skb, 1);
1493
        *ptr = event;
1494
 
1495
        skb->protocol = x25_type_trans(skb, dev);
1496
        netif_rx(skb);
1497
        dev->last_rx = jiffies;         /* timestamp */
1498
}
1499
 
1500
/* Convert line speed in bps to a number used by cyclom 2x code. */
1501
static u8 bps_to_speed_code(u32 bps)
1502
{
1503
        u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1504
 
1505
             if (bps >= 512000) number = 8;
1506
        else if (bps >= 256000) number = 7;
1507
        else if (bps >= 64000)  number = 6;
1508
        else if (bps >= 38400)  number = 5;
1509
        else if (bps >= 19200)  number = 4;
1510
        else if (bps >= 9600)   number = 3;
1511
        else if (bps >= 4800)   number = 2;
1512
        else if (bps >= 2400)   number = 1;
1513
 
1514
        return number;
1515
}
1516
 
1517
/* log base 2 */
1518
static u8 cycx_log2(u32 n)
1519
{
1520
        u8 log = 0;
1521
 
1522
        if (!n)
1523
                return 0;
1524
 
1525
        while (n > 1) {
1526
                n >>= 1;
1527
                ++log;
1528
        }
1529
 
1530
        return log;
1531
}
1532
 
1533
/* Convert decimal string to unsigned integer.
1534
 * If len != 0 then only 'len' characters of the string are converted. */
1535
static unsigned dec_to_uint(u8 *str, int len)
1536
{
1537
        unsigned val = 0;
1538
 
1539
        if (!len)
1540
                len = strlen(str);
1541
 
1542
        for (; len && isdigit(*str); ++str, --len)
1543
                val = (val * 10) + (*str - (unsigned) '0');
1544
 
1545
        return val;
1546
}
1547
 
1548
static void reset_timer(struct net_device *dev)
1549
{
1550
        struct cycx_x25_channel *chan = dev->priv;
1551
 
1552
        if (chan->svc)
1553
                mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
1554
}
1555
#ifdef CYCLOMX_X25_DEBUG
1556
static void cycx_x25_dump_config(struct cycx_x25_config *conf)
1557
{
1558
        printk(KERN_INFO "X.25 configuration\n");
1559
        printk(KERN_INFO "-----------------\n");
1560
        printk(KERN_INFO "link number=%d\n", conf->link);
1561
        printk(KERN_INFO "line speed=%d\n", conf->speed);
1562
        printk(KERN_INFO "clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1563
        printk(KERN_INFO "# level 2 retransm.=%d\n", conf->n2);
1564
        printk(KERN_INFO "level 2 window=%d\n", conf->n2win);
1565
        printk(KERN_INFO "level 3 window=%d\n", conf->n3win);
1566
        printk(KERN_INFO "# logical channels=%d\n", conf->nvc);
1567
        printk(KERN_INFO "level 3 pkt len=%d\n", conf->pktlen);
1568
        printk(KERN_INFO "my address=%d\n", conf->locaddr);
1569
        printk(KERN_INFO "remote address=%d\n", conf->remaddr);
1570
        printk(KERN_INFO "t1=%d seconds\n", conf->t1);
1571
        printk(KERN_INFO "t2=%d seconds\n", conf->t2);
1572
        printk(KERN_INFO "t21=%d seconds\n", conf->t21);
1573
        printk(KERN_INFO "# PVCs=%d\n", conf->npvc);
1574
        printk(KERN_INFO "t23=%d seconds\n", conf->t23);
1575
        printk(KERN_INFO "flags=0x%x\n", conf->flags);
1576
}
1577
 
1578
static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
1579
{
1580
        printk(KERN_INFO "X.25 statistics\n");
1581
        printk(KERN_INFO "--------------\n");
1582
        printk(KERN_INFO "rx_crc_errors=%d\n", stats->rx_crc_errors);
1583
        printk(KERN_INFO "rx_over_errors=%d\n", stats->rx_over_errors);
1584
        printk(KERN_INFO "n2_tx_frames=%d\n", stats->n2_tx_frames);
1585
        printk(KERN_INFO "n2_rx_frames=%d\n", stats->n2_rx_frames);
1586
        printk(KERN_INFO "tx_timeouts=%d\n", stats->tx_timeouts);
1587
        printk(KERN_INFO "rx_timeouts=%d\n", stats->rx_timeouts);
1588
        printk(KERN_INFO "n3_tx_packets=%d\n", stats->n3_tx_packets);
1589
        printk(KERN_INFO "n3_rx_packets=%d\n", stats->n3_rx_packets);
1590
        printk(KERN_INFO "tx_aborts=%d\n", stats->tx_aborts);
1591
        printk(KERN_INFO "rx_aborts=%d\n", stats->rx_aborts);
1592
}
1593
 
1594
static void cycx_x25_dump_devs(struct wan_device *wandev)
1595
{
1596
        struct net_device *dev = wandev->dev;
1597
 
1598
        printk(KERN_INFO "X.25 dev states\n");
1599
        printk(KERN_INFO "name: addr:           txoff:  protocol:\n");
1600
        printk(KERN_INFO "---------------------------------------\n");
1601
 
1602
        while(dev) {
1603
                struct cycx_x25_channel *chan = dev->priv;
1604
 
1605
                printk(KERN_INFO "%-5.5s %-15.15s   %d     ETH_P_%s\n",
1606
                                 chan->name, chan->addr, netif_queue_stopped(dev),
1607
                                 chan->protocol == ETH_P_IP ? "IP" : "X25");
1608
                dev = chan->slave;
1609
        }
1610
}
1611
 
1612
#endif /* CYCLOMX_X25_DEBUG */
1613
/* End */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.