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