at v3.16-rc7 1142 lines 29 kB view raw
1/* Copyright (C) 2007-2008 One Stop Systems 2 * Copyright (C) 2003-2006 SBE, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 16 17#include <linux/types.h> 18#include <linux/netdevice.h> 19#include <linux/module.h> 20#include <linux/hdlc.h> 21#include <linux/if_arp.h> 22#include <linux/init.h> 23#include <asm/uaccess.h> 24#include <linux/rtnetlink.h> 25#include <linux/skbuff.h> 26#include "pmcc4_sysdep.h" 27#include "sbecom_inline_linux.h" 28#include "libsbew.h" 29#include "pmcc4.h" 30#include "pmcc4_ioctls.h" 31#include "pmcc4_private.h" 32#include "sbeproc.h" 33 34/******************************************************************************* 35 * Error out early if we have compiler trouble. 36 * 37 * (This section is included from the kernel's init/main.c as a friendly 38 * spiderman recommendation...) 39 * 40 * Versions of gcc older than that listed below may actually compile and link 41 * okay, but the end product can have subtle run time bugs. To avoid associated 42 * bogus bug reports, we flatly refuse to compile with a gcc that is known to be 43 * too old from the very beginning. 44 */ 45#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2) 46#error Sorry, your GCC is too old. It builds incorrect kernels. 47#endif 48 49#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0 50#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended. 51#endif 52 53/*******************************************************************************/ 54 55#define CHANNAME "hdlc" 56 57/*******************************************************************/ 58/* forward references */ 59status_t c4_chan_work_init(mpi_t *, mch_t *); 60void musycc_wq_chan_restart(void *); 61status_t __init c4_init(ci_t *, u_char *, u_char *); 62status_t __init c4_init2(ci_t *); 63int __init c4hw_attach_all(void); 64void __init hdw_sn_get(hdw_info_t *, int); 65 66#ifdef CONFIG_SBE_PMCC4_NCOMM 67irqreturn_t c4_ebus_intr_th_handler(void *); 68 69#endif 70int c4_frame_rw(ci_t *, struct sbecom_port_param *); 71status_t c4_get_port(ci_t *, int); 72int c4_loop_port(ci_t *, int, u_int8_t); 73int c4_musycc_rw(ci_t *, struct c4_musycc_param *); 74int c4_new_chan(ci_t *, int, int, void *); 75status_t c4_set_port(ci_t *, int); 76int c4_pld_rw(ci_t *, struct sbecom_port_param *); 77void cleanup_devs(void); 78void cleanup_ioremap(void); 79status_t musycc_chan_down(ci_t *, int); 80irqreturn_t musycc_intr_th_handler(void *); 81int musycc_start_xmit(ci_t *, int, void *); 82 83extern ci_t *CI; 84extern struct s_hdw_info hdw_info[]; 85 86int error_flag; /* module load error reporting */ 87int cxt1e1_log_level = LOG_ERROR; 88static int log_level_default = LOG_ERROR; 89module_param(cxt1e1_log_level, int, 0444); 90 91int cxt1e1_max_mru = MUSYCC_MRU; 92static int max_mru_default = MUSYCC_MRU; 93module_param(cxt1e1_max_mru, int, 0444); 94 95int cxt1e1_max_mtu = MUSYCC_MTU; 96int max_mtu_default = MUSYCC_MTU; 97module_param(cxt1e1_max_mtu, int, 0444); 98 99int max_txdesc_used = MUSYCC_TXDESC_MIN; 100int max_txdesc_default = MUSYCC_TXDESC_MIN; 101module_param(max_txdesc_used, int, 0444); 102 103int max_rxdesc_used = MUSYCC_RXDESC_MIN; 104int max_rxdesc_default = MUSYCC_RXDESC_MIN; 105module_param(max_rxdesc_used, int, 0444); 106 107/****************************************************************************/ 108/****************************************************************************/ 109/****************************************************************************/ 110 111void * 112getuserbychan(int channum) 113{ 114 mch_t *ch; 115 116 ch = c4_find_chan(channum); 117 return ch ? ch->user : NULL; 118} 119 120 121char * 122get_hdlc_name(hdlc_device *hdlc) 123{ 124 struct c4_priv *priv = hdlc->priv; 125 struct net_device *dev = getuserbychan(priv->channum); 126 127 return dev->name; 128} 129 130/***************************************************************************/ 131#include <linux/workqueue.h> 132 133/*** 134 * One workqueue (wq) per port (since musycc allows simultaneous group 135 * commands), with individual data for each channel: 136 * 137 * mpi_t -> struct workqueue_struct *wq_port; (dynamically allocated using 138 * create_workqueue()) 139 * 140 * With work structure (work) statically allocated for each channel: 141 * 142 * mch_t -> struct work_struct ch_work; (statically allocated using ???) 143 * 144 ***/ 145 146 147/* 148 * Called by the start transmit routine when a channel TX_ENABLE is to be 149 * issued. This queues the transmission start request among other channels 150 * within a port's group. 151 */ 152void 153c4_wk_chan_restart(mch_t *ch) 154{ 155 mpi_t *pi = ch->up; 156 157#ifdef RLD_RESTART_DEBUG 158 pr_info(">> %s: queueing Port %d Chan %d, mch_t @ %p\n", 159 __func__, pi->portnum, ch->channum, ch); 160#endif 161 162 /* create new entry w/in workqueue for this channel and let'er rip */ 163 164 /** queue_work(struct workqueue_struct *queue, 165 ** struct work_struct *work); 166 **/ 167 queue_work(pi->wq_port, &ch->ch_work); 168} 169 170status_t 171c4_wk_chan_init(mpi_t *pi, mch_t *ch) 172{ 173 /* 174 * this will be used to restart a stopped channel 175 */ 176 177 /** INIT_WORK(struct work_struct *work, 178 ** void (*function)(void *), 179 ** void *data); 180 **/ 181 INIT_WORK(&ch->ch_work, (void *)musycc_wq_chan_restart); 182 return 0; /* success */ 183} 184 185status_t 186c4_wq_port_init(mpi_t *pi) 187{ 188 189 char name[16]; /* NOTE: name of the queue limited by system 190 * to 10 characters */ 191 if (pi->wq_port) 192 return 0; /* already initialized */ 193 194 /* IE pmcc4-01 */ 195 snprintf(name, sizeof(name), "%s%d", pi->up->devname, pi->portnum); 196 197#ifdef RLD_RESTART_DEBUG 198 pr_info(">> %s: creating workqueue <%s> for Port %d.\n", 199 __func__, name, pi->portnum); /* RLD DEBUG */ 200#endif 201 pi->wq_port = create_singlethread_workqueue(name); 202 if (!pi->wq_port) 203 return -ENOMEM; 204 return 0; /* success */ 205} 206 207void 208c4_wq_port_cleanup(mpi_t *pi) 209{ 210 /* 211 * PORT POINT: cannot call this if WQ is statically allocated w/in 212 * structure since it calls kfree(wq); 213 */ 214 if (pi->wq_port) { 215 destroy_workqueue(pi->wq_port); /* this also calls 216 * flush_workqueue() */ 217 pi->wq_port = NULL; 218 } 219} 220 221/***************************************************************************/ 222 223static irqreturn_t 224c4_linux_interrupt(int irq, void *dev_instance) 225{ 226 struct net_device *ndev = dev_instance; 227 228 return musycc_intr_th_handler(netdev_priv(ndev)); 229} 230 231 232#ifdef CONFIG_SBE_PMCC4_NCOMM 233static irqreturn_t 234c4_ebus_interrupt(int irq, void *dev_instance) 235{ 236 struct net_device *ndev = dev_instance; 237 238 return c4_ebus_intr_th_handler(netdev_priv(ndev)); 239} 240#endif 241 242 243static int 244void_open(struct net_device *ndev) 245{ 246 pr_info("%s: trying to open master device !\n", ndev->name); 247 return -1; 248} 249 250 251static int 252chan_open(struct net_device *ndev) 253{ 254 hdlc_device *hdlc = dev_to_hdlc(ndev); 255 const struct c4_priv *priv = hdlc->priv; 256 int ret; 257 258 ret = hdlc_open(ndev); 259 if (ret) { 260 pr_info("hdlc_open failure, err %d.\n", ret); 261 return ret; 262 } 263 264 ret = c4_chan_up(priv->ci, priv->channum); 265 if (ret < 0) 266 return ret; 267 try_module_get(THIS_MODULE); 268 netif_start_queue(ndev); 269 return 0; /* no error = success */ 270} 271 272 273static int 274chan_close(struct net_device *ndev) 275{ 276 hdlc_device *hdlc = dev_to_hdlc(ndev); 277 const struct c4_priv *priv = hdlc->priv; 278 279 netif_stop_queue(ndev); 280 musycc_chan_down((ci_t *) 0, priv->channum); 281 hdlc_close(ndev); 282 module_put(THIS_MODULE); 283 return 0; 284} 285 286 287static int 288chan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 289{ 290 return hdlc_ioctl(dev, ifr, cmd); 291} 292 293 294static int 295chan_attach_noop(struct net_device *ndev, unsigned short foo_1, 296 unsigned short foo_2) 297{ 298 /* our driver has nothing to do here, show's 299 * over, go home 300 */ 301 return 0; 302} 303 304 305static struct net_device_stats * 306chan_get_stats(struct net_device *ndev) 307{ 308 mch_t *ch; 309 struct net_device_stats *nstats; 310 struct sbecom_chan_stats *stats; 311 int channum; 312 313 { 314 struct c4_priv *priv; 315 316 priv = (struct c4_priv *)dev_to_hdlc(ndev)->priv; 317 channum = priv->channum; 318 } 319 320 ch = c4_find_chan(channum); 321 if (ch == NULL) 322 return NULL; 323 324 nstats = &ndev->stats; 325 stats = &ch->s; 326 327 memset(nstats, 0, sizeof(struct net_device_stats)); 328 nstats->rx_packets = stats->rx_packets; 329 nstats->tx_packets = stats->tx_packets; 330 nstats->rx_bytes = stats->rx_bytes; 331 nstats->tx_bytes = stats->tx_bytes; 332 nstats->rx_errors = stats->rx_length_errors + 333 stats->rx_over_errors + 334 stats->rx_crc_errors + 335 stats->rx_frame_errors + 336 stats->rx_fifo_errors + 337 stats->rx_missed_errors; 338 nstats->tx_errors = stats->tx_dropped + 339 stats->tx_aborted_errors + 340 stats->tx_fifo_errors; 341 nstats->rx_dropped = stats->rx_dropped; 342 nstats->tx_dropped = stats->tx_dropped; 343 344 nstats->rx_length_errors = stats->rx_length_errors; 345 nstats->rx_over_errors = stats->rx_over_errors; 346 nstats->rx_crc_errors = stats->rx_crc_errors; 347 nstats->rx_frame_errors = stats->rx_frame_errors; 348 nstats->rx_fifo_errors = stats->rx_fifo_errors; 349 nstats->rx_missed_errors = stats->rx_missed_errors; 350 351 nstats->tx_aborted_errors = stats->tx_aborted_errors; 352 nstats->tx_fifo_errors = stats->tx_fifo_errors; 353 354 return nstats; 355} 356 357 358static ci_t * 359get_ci_by_dev(struct net_device *ndev) 360{ 361 return (ci_t *)(netdev_priv(ndev)); 362} 363 364 365static int 366c4_linux_xmit(struct sk_buff *skb, struct net_device *ndev) 367{ 368 const struct c4_priv *priv; 369 int rval; 370 371 hdlc_device *hdlc = dev_to_hdlc(ndev); 372 373 priv = hdlc->priv; 374 375 rval = musycc_start_xmit(priv->ci, priv->channum, skb); 376 return rval; 377} 378 379static const struct net_device_ops chan_ops = { 380 .ndo_open = chan_open, 381 .ndo_stop = chan_close, 382 .ndo_start_xmit = c4_linux_xmit, 383 .ndo_do_ioctl = chan_dev_ioctl, 384 .ndo_get_stats = chan_get_stats, 385}; 386 387static struct net_device * 388create_chan(struct net_device *ndev, ci_t *ci, 389 struct sbecom_chan_param *cp) 390{ 391 hdlc_device *hdlc; 392 struct net_device *dev; 393 hdw_info_t *hi; 394 int ret; 395 396 if (c4_find_chan(cp->channum)) 397 return NULL; /* channel already exists */ 398 399 { 400 struct c4_priv *priv; 401 402 /* allocate then fill in private data structure */ 403 priv = kzalloc(sizeof(struct c4_priv), GFP_KERNEL); 404 if (!priv) { 405 pr_warning("%s: no memory for net_device !\n", 406 ci->devname); 407 return NULL; 408 } 409 dev = alloc_hdlcdev(priv); 410 if (!dev) { 411 pr_warning("%s: no memory for hdlc_device !\n", 412 ci->devname); 413 kfree(priv); 414 return NULL; 415 } 416 priv->ci = ci; 417 priv->channum = cp->channum; 418 } 419 420 hdlc = dev_to_hdlc(dev); 421 422 dev->base_addr = 0; /* not I/O mapped */ 423 dev->irq = ndev->irq; 424 dev->type = ARPHRD_RAWHDLC; 425 *dev->name = 0; /* default ifconfig name = "hdlc" */ 426 427 hi = (hdw_info_t *)ci->hdw_info; 428 if (hi->mfg_info_sts == EEPROM_OK) { 429 switch (hi->promfmt) { 430 case PROM_FORMAT_TYPE1: 431 memcpy(dev->dev_addr, 432 (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6); 433 break; 434 case PROM_FORMAT_TYPE2: 435 memcpy(dev->dev_addr, 436 (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6); 437 break; 438 default: 439 memset(dev->dev_addr, 0, 6); 440 break; 441 } 442 } else 443 memset(dev->dev_addr, 0, 6); 444 445 hdlc->xmit = c4_linux_xmit; 446 447 dev->netdev_ops = &chan_ops; 448 /* 449 * The native hdlc stack calls this 'attach' routine during 450 * hdlc_raw_ioctl(), passing parameters for line encoding and parity. 451 * Since hdlc_raw_ioctl() stack does not interrogate whether an 'attach' 452 * routine is actually registered or not, we supply a dummy routine which 453 * does nothing (since encoding and parity are setup for our driver via a 454 * special configuration application). 455 */ 456 457 hdlc->attach = chan_attach_noop; 458 459 /* needed due to Ioctl calling sequence */ 460 rtnl_unlock(); 461 ret = register_hdlc_device(dev); 462 /* NOTE: <stats> setting must occur AFTER registration in order to "take" */ 463 dev->tx_queue_len = MAX_DEFAULT_IFQLEN; 464 465 /* needed due to Ioctl calling sequence */ 466 rtnl_lock(); 467 if (ret) { 468 if (cxt1e1_log_level >= LOG_WARN) 469 pr_info("%s: create_chan[%d] registration error = %d.\n", 470 ci->devname, cp->channum, ret); 471 /* cleanup */ 472 free_netdev(dev); 473 /* failed to register */ 474 return NULL; 475 } 476 return dev; 477} 478 479 480/* the idea here is to get port information and pass it back (using pointer) */ 481static status_t 482do_get_port(struct net_device *ndev, void *data) 483{ 484 int ret; 485 ci_t *ci; /* ci stands for card information */ 486 struct sbecom_port_param pp;/* copy data to kernel land */ 487 488 if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param))) 489 return -EFAULT; 490 if (pp.portnum >= MUSYCC_NPORTS) 491 return -EFAULT; 492 ci = get_ci_by_dev(ndev); 493 if (!ci) 494 return -EINVAL; /* get card info */ 495 496 ret = c4_get_port(ci, pp.portnum); 497 if (ret < 0) 498 return ret; 499 if (copy_to_user(data, &ci->port[pp.portnum].p, 500 sizeof(struct sbecom_port_param))) 501 return -EFAULT; 502 return 0; 503} 504 505/* this function copys the user data and then calls the real action function */ 506static status_t 507do_set_port(struct net_device *ndev, void *data) 508{ 509 ci_t *ci; /* ci stands for card information */ 510 struct sbecom_port_param pp;/* copy data to kernel land */ 511 512 if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param))) 513 return -EFAULT; 514 if (pp.portnum >= MUSYCC_NPORTS) 515 return -EFAULT; 516 ci = get_ci_by_dev(ndev); 517 if (!ci) 518 return -EINVAL; /* get card info */ 519 520 if (pp.portnum >= ci->max_port) /* sanity check */ 521 return -ENXIO; 522 523 memcpy(&ci->port[pp.portnum].p, &pp, sizeof(struct sbecom_port_param)); 524 return c4_set_port(ci, pp.portnum); 525} 526 527/* work the port loopback mode as per directed */ 528static status_t 529do_port_loop(struct net_device *ndev, void *data) 530{ 531 struct sbecom_port_param pp; 532 ci_t *ci; 533 534 if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param))) 535 return -EFAULT; 536 ci = get_ci_by_dev(ndev); 537 if (!ci) 538 return -EINVAL; 539 return c4_loop_port(ci, pp.portnum, pp.port_mode); 540} 541 542/* set the specified register with the given value / or just read it */ 543static status_t 544do_framer_rw(struct net_device *ndev, void *data) 545{ 546 struct sbecom_port_param pp; 547 ci_t *ci; 548 int ret; 549 550 if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param))) 551 return -EFAULT; 552 ci = get_ci_by_dev(ndev); 553 if (!ci) 554 return -EINVAL; 555 ret = c4_frame_rw(ci, &pp); 556 if (ret < 0) 557 return ret; 558 if (copy_to_user(data, &pp, sizeof(struct sbecom_port_param))) 559 return -EFAULT; 560 return 0; 561} 562 563/* set the specified register with the given value / or just read it */ 564static status_t 565do_pld_rw(struct net_device *ndev, void *data) 566{ 567 struct sbecom_port_param pp; 568 ci_t *ci; 569 int ret; 570 571 if (copy_from_user(&pp, data, sizeof(struct sbecom_port_param))) 572 return -EFAULT; 573 ci = get_ci_by_dev(ndev); 574 if (!ci) 575 return -EINVAL; 576 577 ret = c4_pld_rw(ci, &pp); 578 if (ret) 579 return ret; 580 if (copy_to_user(data, &pp, sizeof(struct sbecom_port_param))) 581 return -EFAULT; 582 return 0; 583} 584 585/* set the specified register with the given value / or just read it */ 586static status_t 587do_musycc_rw(struct net_device *ndev, void *data) 588{ 589 struct c4_musycc_param mp; 590 ci_t *ci; 591 int ret; 592 593 if (copy_from_user(&mp, data, sizeof(struct c4_musycc_param))) 594 return -EFAULT; 595 ci = get_ci_by_dev(ndev); 596 if (!ci) 597 return -EINVAL; 598 ret = c4_musycc_rw(ci, &mp); 599 if (ret < 0) 600 return ret; 601 if (copy_to_user(data, &mp, sizeof(struct c4_musycc_param))) 602 return -EFAULT; 603 return 0; 604} 605 606static status_t 607do_get_chan(struct net_device *ndev, void *data) 608{ 609 struct sbecom_chan_param cp; 610 int ret; 611 612 if (copy_from_user(&cp, data, 613 sizeof(struct sbecom_chan_param))) 614 return -EFAULT; 615 616 ret = c4_get_chan(cp.channum, &cp); 617 if (ret < 0) 618 return ret; 619 620 if (copy_to_user(data, &cp, sizeof(struct sbecom_chan_param))) 621 return -EFAULT; 622 return 0; 623} 624 625static status_t 626do_set_chan(struct net_device *ndev, void *data) 627{ 628 struct sbecom_chan_param cp; 629 ci_t *ci; 630 631 if (copy_from_user(&cp, data, sizeof(struct sbecom_chan_param))) 632 return -EFAULT; 633 ci = get_ci_by_dev(ndev); 634 if (!ci) 635 return -EINVAL; 636 return c4_set_chan(cp.channum, &cp); 637} 638 639static status_t 640do_create_chan(struct net_device *ndev, void *data) 641{ 642 ci_t *ci; 643 struct net_device *dev; 644 struct sbecom_chan_param cp; 645 int ret; 646 647 if (copy_from_user(&cp, data, sizeof(struct sbecom_chan_param))) 648 return -EFAULT; 649 ci = get_ci_by_dev(ndev); 650 if (!ci) 651 return -EINVAL; 652 dev = create_chan(ndev, ci, &cp); 653 if (!dev) 654 return -EBUSY; 655 ret = c4_new_chan(ci, cp.port, cp.channum, dev); 656 if (ret < 0) { 657 /* needed due to Ioctl calling sequence */ 658 rtnl_unlock(); 659 unregister_hdlc_device(dev); 660 /* needed due to Ioctl calling sequence */ 661 rtnl_lock(); 662 free_netdev(dev); 663 } 664 return ret; 665} 666 667static status_t 668do_get_chan_stats(struct net_device *ndev, void *data) 669{ 670 struct c4_chan_stats_wrap ccs; 671 int ret; 672 673 if (copy_from_user(&ccs, data, 674 sizeof(struct c4_chan_stats_wrap))) 675 return -EFAULT; 676 677 ret = c4_get_chan_stats(ccs.channum, &ccs.stats); 678 if (ret < 0) 679 return ret; 680 681 if (copy_to_user(data, &ccs, 682 sizeof(struct c4_chan_stats_wrap))) 683 return -EFAULT; 684 return 0; 685} 686static status_t 687do_set_loglevel(struct net_device *ndev, void *data) 688{ 689 unsigned int cxt1e1_log_level; 690 691 if (copy_from_user(&cxt1e1_log_level, data, sizeof(int))) 692 return -EFAULT; 693 sbecom_set_loglevel(cxt1e1_log_level); 694 return 0; 695} 696 697static status_t 698do_deluser(struct net_device *ndev, int lockit) 699{ 700 if (ndev->flags & IFF_UP) 701 return -EBUSY; 702 703 { 704 ci_t *ci; 705 mch_t *ch; 706 const struct c4_priv *priv; 707 int channum; 708 709 priv = (struct c4_priv *)dev_to_hdlc(ndev)->priv; 710 ci = priv->ci; 711 channum = priv->channum; 712 713 ch = c4_find_chan(channum); 714 if (ch == NULL) 715 return -ENOENT; 716 ch->user = NULL; /* will be freed, below */ 717 } 718 719 /* needed if Ioctl calling sequence */ 720 if (lockit) 721 rtnl_unlock(); 722 unregister_hdlc_device(ndev); 723 /* needed if Ioctl calling sequence */ 724 if (lockit) 725 rtnl_lock(); 726 free_netdev(ndev); 727 return 0; 728} 729 730int 731do_del_chan(struct net_device *musycc_dev, void *data) 732{ 733 struct sbecom_chan_param cp; 734 char buf[sizeof(CHANNAME) + 3]; 735 struct net_device *dev; 736 int ret; 737 738 if (copy_from_user(&cp, data, 739 sizeof(struct sbecom_chan_param))) 740 return -EFAULT; 741 if (cp.channum > 999) 742 return -EINVAL; 743 snprintf(buf, sizeof(buf), CHANNAME "%d", cp.channum); 744 dev = __dev_get_by_name(&init_net, buf); 745 if (!dev) 746 return -ENODEV; 747 ret = do_deluser(dev, 1); 748 if (ret) 749 return ret; 750 return c4_del_chan(cp.channum); 751} 752int c4_reset_board(void *); 753 754int 755do_reset(struct net_device *musycc_dev, void *data) 756{ 757 const struct c4_priv *priv; 758 int i; 759 760 for (i = 0; i < 128; i++) { 761 struct net_device *ndev; 762 char buf[sizeof(CHANNAME) + 3]; 763 764 sprintf(buf, CHANNAME "%d", i); 765 ndev = __dev_get_by_name(&init_net, buf); 766 if (!ndev) 767 continue; 768 priv = dev_to_hdlc(ndev)->priv; 769 770 if ((unsigned long) (priv->ci) == 771 (unsigned long) (netdev_priv(musycc_dev))) { 772 ndev->flags &= ~IFF_UP; 773 netif_stop_queue(ndev); 774 do_deluser(ndev, 1); 775 } 776 } 777 return 0; 778} 779 780int 781do_reset_chan_stats(struct net_device *musycc_dev, void *data) 782{ 783 struct sbecom_chan_param cp; 784 785 if (copy_from_user(&cp, data, 786 sizeof(struct sbecom_chan_param))) 787 return -EFAULT; 788 return c4_del_chan_stats(cp.channum); 789} 790 791static status_t 792c4_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) 793{ 794 ci_t *ci; 795 void *data; 796 int iocmd, iolen; 797 status_t ret; 798 static struct data { 799 union { 800 u_int8_t c; 801 u_int32_t i; 802 struct sbe_brd_info bip; 803 struct sbe_drv_info dip; 804 struct sbe_iid_info iip; 805 struct sbe_brd_addr bap; 806 struct sbecom_chan_stats stats; 807 struct sbecom_chan_param param; 808 struct temux_card_stats cards; 809 struct sbecom_card_param cardp; 810 struct sbecom_framer_param frp; 811 } u; 812 } arg; 813 814 815 if (!capable(CAP_SYS_ADMIN)) 816 return -EPERM; 817 if (cmd != SIOCDEVPRIVATE + 15) 818 return -EINVAL; 819 ci = get_ci_by_dev(ndev); 820 if (!ci) 821 return -EINVAL; 822 if (ci->state != C_RUNNING) 823 return -ENODEV; 824 if (copy_from_user(&iocmd, ifr->ifr_data, sizeof(iocmd))) 825 return -EFAULT; 826#if 0 827 if (copy_from_user(&len, ifr->ifr_data + sizeof(iocmd), sizeof(len))) 828 return -EFAULT; 829#endif 830 831#if 0 832 pr_info("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd, 833 _IOC_DIR(iocmd), _IOC_TYPE(iocmd), _IOC_NR(iocmd), 834 _IOC_SIZE(iocmd)); 835#endif 836 iolen = _IOC_SIZE(iocmd); 837 if (iolen > sizeof(arg)) 838 return -EFAULT; 839 data = ifr->ifr_data + sizeof(iocmd); 840 if (copy_from_user(&arg, data, iolen)) 841 return -EFAULT; 842 843 ret = 0; 844 switch (iocmd) { 845 case SBE_IOC_PORT_GET: 846 ret = do_get_port(ndev, data); 847 break; 848 case SBE_IOC_PORT_SET: 849 ret = do_set_port(ndev, data); 850 break; 851 case SBE_IOC_CHAN_GET: 852 ret = do_get_chan(ndev, data); 853 break; 854 case SBE_IOC_CHAN_SET: 855 ret = do_set_chan(ndev, data); 856 break; 857 case C4_DEL_CHAN: 858 ret = do_del_chan(ndev, data); 859 break; 860 case SBE_IOC_CHAN_NEW: 861 ret = do_create_chan(ndev, data); 862 break; 863 case SBE_IOC_CHAN_GET_STAT: 864 ret = do_get_chan_stats(ndev, data); 865 break; 866 case SBE_IOC_LOGLEVEL: 867 ret = do_set_loglevel(ndev, data); 868 break; 869 case SBE_IOC_RESET_DEV: 870 ret = do_reset(ndev, data); 871 break; 872 case SBE_IOC_CHAN_DEL_STAT: 873 ret = do_reset_chan_stats(ndev, data); 874 break; 875 case C4_LOOP_PORT: 876 ret = do_port_loop(ndev, data); 877 break; 878 case C4_RW_FRMR: 879 ret = do_framer_rw(ndev, data); 880 break; 881 case C4_RW_MSYC: 882 ret = do_musycc_rw(ndev, data); 883 break; 884 case C4_RW_PLD: 885 ret = do_pld_rw(ndev, data); 886 break; 887 case SBE_IOC_IID_GET: 888 ret = (iolen == sizeof(struct sbe_iid_info)) ? 889 c4_get_iidinfo(ci, &arg.u.iip) : -EFAULT; 890 if (ret == 0) /* no error, copy data */ 891 if (copy_to_user(data, &arg, iolen)) 892 return -EFAULT; 893 break; 894 default: 895 ret = -EINVAL; 896 break; 897 } 898 return ret; 899} 900 901static const struct net_device_ops c4_ops = { 902 .ndo_open = void_open, 903 .ndo_start_xmit = c4_linux_xmit, 904 .ndo_do_ioctl = c4_ioctl, 905}; 906 907static void c4_setup(struct net_device *dev) 908{ 909 dev->type = ARPHRD_VOID; 910 dev->netdev_ops = &c4_ops; 911} 912 913struct net_device *__init 914c4_add_dev(hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1, 915 int irq0, int irq1) 916{ 917 struct net_device *ndev; 918 ci_t *ci; 919 920 ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup); 921 if (!ndev) { 922 pr_warning("%s: no memory for struct net_device !\n", 923 hi->devname); 924 error_flag = -ENOMEM; 925 return NULL; 926 } 927 ci = (ci_t *)(netdev_priv(ndev)); 928 ndev->irq = irq0; 929 930 ci->hdw_info = hi; 931 ci->state = C_INIT; /* mark as hardware not available */ 932 ci->next = c4_list; 933 c4_list = ci; 934 ci->brdno = ci->next ? ci->next->brdno + 1 : 0; 935 936 if (!CI) 937 CI = ci; /* DEBUG, only board 0 usage */ 938 939 strcpy(ci->devname, hi->devname); 940 941 /* tasklet */ 942#if defined(SBE_ISR_TASKLET) 943 tasklet_init(&ci->ci_musycc_isr_tasklet, 944 (void (*) (unsigned long)) musycc_intr_bh_tasklet, 945 (unsigned long) ci); 946 947 if (atomic_read(&ci->ci_musycc_isr_tasklet.count) == 0) 948 tasklet_disable_nosync(&ci->ci_musycc_isr_tasklet); 949#elif defined(SBE_ISR_IMMEDIATE) 950 ci->ci_musycc_isr_tq.routine = (void *)(unsigned long)musycc_intr_bh_tasklet; 951 ci->ci_musycc_isr_tq.data = ci; 952#endif 953 954 955 if (register_netdev(ndev) || 956 (c4_init(ci, (u_char *) f0, (u_char *) f1) != SBE_DRVR_SUCCESS)) { 957 kfree(netdev_priv(ndev)); 958 kfree(ndev); 959 error_flag = -ENODEV; 960 return NULL; 961 } 962 /************************************************************* 963 * int request_irq(unsigned int irq, 964 * void (*handler)(int, void *, struct pt_regs *), 965 * unsigned long flags, const char *dev_name, void *dev_id); 966 * wherein: 967 * irq -> The interrupt number that is being requested. 968 * handler -> Pointer to handling function being installed. 969 * flags -> A bit mask of options related to interrupt management. 970 * dev_name -> String used in /proc/interrupts to show owner of interrupt. 971 * dev_id -> Pointer (for shared interrupt lines) to point to its own 972 * private data area (to identify which device is interrupting). 973 * 974 * extern void free_irq(unsigned int irq, void *dev_id); 975 **************************************************************/ 976 977 if (request_irq(irq0, &c4_linux_interrupt, 978 IRQF_SHARED, 979 ndev->name, ndev)) { 980 pr_warning("%s: MUSYCC could not get irq: %d\n", 981 ndev->name, irq0); 982 unregister_netdev(ndev); 983 kfree(netdev_priv(ndev)); 984 kfree(ndev); 985 error_flag = -EIO; 986 return NULL; 987 } 988#ifdef CONFIG_SBE_PMCC4_NCOMM 989 if (request_irq(irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev)) { 990 pr_warning("%s: EBUS could not get irq: %d\n", hi->devname, irq1); 991 unregister_netdev(ndev); 992 free_irq(irq0, ndev); 993 kfree(netdev_priv(ndev)); 994 kfree(ndev); 995 error_flag = -EIO; 996 return NULL; 997 } 998#endif 999 1000 /* setup board identification information */ 1001 1002 { 1003 u_int32_t tmp; 1004 1005 /* also sets PROM format type (promfmt) for later usage */ 1006 hdw_sn_get(hi, brdno); 1007 1008 switch (hi->promfmt) { 1009 case PROM_FORMAT_TYPE1: 1010 memcpy(ndev->dev_addr, 1011 (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6); 1012 /* unaligned data acquisition */ 1013 memcpy(&tmp, (FLD_TYPE1 *) (hi->mfg_info.pft1.Id), 4); 1014 ci->brd_id = cpu_to_be32(tmp); 1015 break; 1016 case PROM_FORMAT_TYPE2: 1017 memcpy(ndev->dev_addr, 1018 (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6); 1019 /* unaligned data acquisition */ 1020 memcpy(&tmp, (FLD_TYPE2 *) (hi->mfg_info.pft2.Id), 4); 1021 ci->brd_id = cpu_to_be32(tmp); 1022 break; 1023 default: 1024 ci->brd_id = 0; 1025 memset(ndev->dev_addr, 0, 6); 1026 break; 1027 } 1028 1029#if 1 1030 /* requires bid to be preset */ 1031 sbeid_set_hdwbid(ci); 1032#else 1033 /* requires hdw_bid to be preset */ 1034 sbeid_set_bdtype(ci); 1035#endif 1036 } 1037 1038#ifdef CONFIG_PROC_FS 1039 sbecom_proc_brd_init(ci); 1040#endif 1041#if defined(SBE_ISR_TASKLET) 1042 tasklet_enable(&ci->ci_musycc_isr_tasklet); 1043#endif 1044 1045 error_flag = c4_init2(ci); 1046 if (error_flag != SBE_DRVR_SUCCESS) { 1047#ifdef CONFIG_PROC_FS 1048 sbecom_proc_brd_cleanup(ci); 1049#endif 1050 unregister_netdev(ndev); 1051 free_irq(irq1, ndev); 1052 free_irq(irq0, ndev); 1053 kfree(netdev_priv(ndev)); 1054 kfree(ndev); 1055 /* failure, error_flag is set */ 1056 return NULL; 1057 } 1058 return ndev; 1059} 1060 1061static int __init 1062c4_mod_init(void) 1063{ 1064 int rtn; 1065 1066 rtn = c4hw_attach_all(); 1067 if (rtn) 1068 return -rtn; /* installation failure - see system log */ 1069 1070 /* housekeeping notifications */ 1071 if (cxt1e1_log_level != log_level_default) 1072 pr_info("NOTE: driver parameter <cxt1e1_log_level> changed from default %d to %d.\n", 1073 log_level_default, cxt1e1_log_level); 1074 if (cxt1e1_max_mru != max_mru_default) 1075 pr_info("NOTE: driver parameter <cxt1e1_max_mru> changed from default %d to %d.\n", 1076 max_mru_default, cxt1e1_max_mru); 1077 if (cxt1e1_max_mtu != max_mtu_default) 1078 pr_info("NOTE: driver parameter <cxt1e1_max_mtu> changed from default %d to %d.\n", 1079 max_mtu_default, cxt1e1_max_mtu); 1080 if (max_rxdesc_used != max_rxdesc_default) { 1081 if (max_rxdesc_used > 2000) 1082 max_rxdesc_used = 2000; /* out-of-bounds reset */ 1083 pr_info("NOTE: driver parameter <max_rxdesc_used> changed from default %d to %d.\n", 1084 max_rxdesc_default, max_rxdesc_used); 1085 } 1086 if (max_txdesc_used != max_txdesc_default) { 1087 if (max_txdesc_used > 1000) 1088 max_txdesc_used = 1000; /* out-of-bounds reset */ 1089 pr_info("NOTE: driver parameter <max_txdesc_used> changed from default %d to %d.\n", 1090 max_txdesc_default, max_txdesc_used); 1091 } 1092 return 0; /* installation success */ 1093} 1094 1095 1096 /* 1097 * find any still allocated hdlc registrations and unregister via call to 1098 * do_deluser() 1099 */ 1100 1101static void __exit 1102cleanup_hdlc(void) 1103{ 1104 hdw_info_t *hi; 1105 ci_t *ci; 1106 struct net_device *ndev; 1107 int i, j, k; 1108 1109 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++) { 1110 if (hi->ndev) { /* a board has been attached */ 1111 ci = (ci_t *)(netdev_priv(hi->ndev)); 1112 for (j = 0; j < ci->max_port; j++) 1113 for (k = 0; k < MUSYCC_NCHANS; k++) { 1114 ndev = ci->port[j].chan[k]->user; 1115 if (ndev) 1116 do_deluser(ndev, 0); 1117 } 1118 } 1119 } 1120} 1121 1122 1123static void __exit 1124c4_mod_remove(void) 1125{ 1126 cleanup_hdlc(); /* delete any missed channels */ 1127 cleanup_devs(); 1128 c4_cleanup(); 1129 cleanup_ioremap(); 1130 pr_info("SBE - driver removed.\n"); 1131} 1132 1133module_init(c4_mod_init); 1134module_exit(c4_mod_remove); 1135 1136MODULE_AUTHOR("SBE Technical Services <support@sbei.com>"); 1137MODULE_DESCRIPTION("wanPCI-CxT1E1 Generic HDLC WAN Driver module"); 1138#ifdef MODULE_LICENSE 1139MODULE_LICENSE("GPL"); 1140#endif 1141 1142/*** End-of-File ***/