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