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