Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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