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