PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / staging / cxt1e1 / linux.c
blob4a08e16e42f719470cd9a0b63de557d2b3ff704b
1 /* Copyright (C) 2007-2008 One Stop Systems
2 * Copyright (C) 2003-2006 SBE, Inc.
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.
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.
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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"
34 /*****************************************************************************************
35 * Error out early if we have compiler trouble.
37 * (This section is included from the kernel's init/main.c as a friendly
38 * spiderman recommendation...)
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.
45 #if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
46 #error Sorry, your GCC is too old. It builds incorrect kernels.
47 #endif
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
53 /*****************************************************************************************/
55 #define CHANNAME "hdlc"
57 /*******************************************************************/
58 /* forward references */
59 status_t c4_chan_work_init (mpi_t *, mch_t *);
60 void musycc_wq_chan_restart (void *);
61 status_t __init c4_init (ci_t *, u_char *, u_char *);
62 status_t __init c4_init2 (ci_t *);
63 ci_t *__init c4_new (void *);
64 int __init c4hw_attach_all (void);
65 void __init hdw_sn_get (hdw_info_t *, int);
67 #ifdef CONFIG_SBE_PMCC4_NCOMM
68 irqreturn_t c4_ebus_intr_th_handler (void *);
70 #endif
71 int c4_frame_rw (ci_t *, struct sbecom_port_param *);
72 status_t c4_get_port (ci_t *, int);
73 int c4_loop_port (ci_t *, int, u_int8_t);
74 int c4_musycc_rw (ci_t *, struct c4_musycc_param *);
75 int c4_new_chan (ci_t *, int, int, void *);
76 status_t c4_set_port (ci_t *, int);
77 int c4_pld_rw (ci_t *, struct sbecom_port_param *);
78 void cleanup_devs (void);
79 void cleanup_ioremap (void);
80 status_t musycc_chan_down (ci_t *, int);
81 irqreturn_t musycc_intr_th_handler (void *);
82 int musycc_start_xmit (ci_t *, int, void *);
84 extern char pmcc4_OSSI_release[];
85 extern ci_t *CI;
86 extern struct s_hdw_info hdw_info[];
88 #if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \
89 defined(CONFIG_SBE_HDLC_V7_MODULE) || defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE)
90 #define _v7_hdlc_ 1
91 #else
92 #define _v7_hdlc_ 0
93 #endif
95 #if _v7_hdlc_
96 #define V7(x) (x ## _v7)
97 extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *);
98 extern int register_hdlc_device_v7 (hdlc_device *);
99 extern int unregister_hdlc_device_v7 (hdlc_device *);
101 #else
102 #define V7(x) x
103 #endif
105 int error_flag; /* module load error reporting */
106 int cxt1e1_log_level = LOG_ERROR;
107 int log_level_default = LOG_ERROR;
108 module_param(cxt1e1_log_level, int, 0444);
110 int cxt1e1_max_mru = MUSYCC_MRU;
111 int max_mru_default = MUSYCC_MRU;
112 module_param(cxt1e1_max_mru, int, 0444);
114 int cxt1e1_max_mtu = MUSYCC_MTU;
115 int max_mtu_default = MUSYCC_MTU;
116 module_param(cxt1e1_max_mtu, int, 0444);
118 int max_txdesc_used = MUSYCC_TXDESC_MIN;
119 int max_txdesc_default = MUSYCC_TXDESC_MIN;
120 module_param(max_txdesc_used, int, 0444);
122 int max_rxdesc_used = MUSYCC_RXDESC_MIN;
123 int max_rxdesc_default = MUSYCC_RXDESC_MIN;
124 module_param(max_rxdesc_used, int, 0444);
126 /****************************************************************************/
127 /****************************************************************************/
128 /****************************************************************************/
130 void *
131 getuserbychan (int channum)
133 mch_t *ch;
135 ch = c4_find_chan (channum);
136 return ch ? ch->user : NULL;
140 char *
141 get_hdlc_name (hdlc_device *hdlc)
143 struct c4_priv *priv = hdlc->priv;
144 struct net_device *dev = getuserbychan (priv->channum);
146 return dev->name;
150 static status_t
151 mkret (int bsd)
153 if (bsd > 0)
154 return -bsd;
155 else
156 return bsd;
159 /***************************************************************************/
160 #include <linux/workqueue.h>
162 /***
163 * One workqueue (wq) per port (since musycc allows simultaneous group
164 * commands), with individual data for each channel:
166 * mpi_t -> struct workqueue_struct *wq_port; (dynamically allocated using
167 * create_workqueue())
169 * With work structure (work) statically allocated for each channel:
171 * mch_t -> struct work_struct ch_work; (statically allocated using ???)
173 ***/
177 * Called by the start transmit routine when a channel TX_ENABLE is to be
178 * issued. This queues the transmission start request among other channels
179 * within a port's group.
181 void
182 c4_wk_chan_restart (mch_t *ch)
184 mpi_t *pi = ch->up;
186 #ifdef RLD_RESTART_DEBUG
187 pr_info(">> %s: queueing Port %d Chan %d, mch_t @ %p\n",
188 __func__, pi->portnum, ch->channum, ch);
189 #endif
191 /* create new entry w/in workqueue for this channel and let'er rip */
193 /** queue_work (struct workqueue_struct *queue,
194 ** struct work_struct *work);
196 queue_work (pi->wq_port, &ch->ch_work);
199 status_t
200 c4_wk_chan_init (mpi_t *pi, mch_t *ch)
203 * this will be used to restart a stopped channel
206 /** INIT_WORK (struct work_struct *work,
207 ** void (*function)(void *),
208 ** void *data);
210 INIT_WORK(&ch->ch_work, (void *)musycc_wq_chan_restart);
211 return 0; /* success */
214 status_t
215 c4_wq_port_init (mpi_t *pi)
218 char name[16], *np; /* NOTE: name of the queue limited by system
219 * to 10 characters */
221 if (pi->wq_port)
222 return 0; /* already initialized */
224 np = name;
225 memset (name, 0, 16);
226 sprintf (np, "%s%d", pi->up->devname, pi->portnum); /* IE pmcc4-01) */
228 #ifdef RLD_RESTART_DEBUG
229 pr_info(">> %s: creating workqueue <%s> for Port %d.\n",
230 __func__, name, pi->portnum); /* RLD DEBUG */
231 #endif
232 if (!(pi->wq_port = create_singlethread_workqueue (name)))
233 return -ENOMEM;
234 return 0; /* success */
237 void
238 c4_wq_port_cleanup (mpi_t *pi)
241 * PORT POINT: cannot call this if WQ is statically allocated w/in
242 * structure since it calls kfree(wq);
244 if (pi->wq_port)
246 destroy_workqueue (pi->wq_port); /* this also calls
247 * flush_workqueue() */
248 pi->wq_port = NULL;
252 /***************************************************************************/
254 irqreturn_t
255 c4_linux_interrupt (int irq, void *dev_instance)
257 struct net_device *ndev = dev_instance;
259 return musycc_intr_th_handler(netdev_priv(ndev));
263 #ifdef CONFIG_SBE_PMCC4_NCOMM
264 irqreturn_t
265 c4_ebus_interrupt (int irq, void *dev_instance)
267 struct net_device *ndev = dev_instance;
269 return c4_ebus_intr_th_handler(netdev_priv(ndev));
271 #endif
274 static int
275 void_open (struct net_device *ndev)
277 pr_info("%s: trying to open master device !\n", ndev->name);
278 return -1;
282 static int
283 chan_open (struct net_device *ndev)
285 hdlc_device *hdlc = dev_to_hdlc (ndev);
286 const struct c4_priv *priv = hdlc->priv;
287 int ret;
289 if ((ret = hdlc_open (ndev)))
291 pr_info("hdlc_open failure, err %d.\n", ret);
292 return ret;
294 if ((ret = c4_chan_up (priv->ci, priv->channum)))
295 return -ret;
296 try_module_get (THIS_MODULE);
297 netif_start_queue (ndev);
298 return 0; /* no error = success */
302 static int
303 chan_close (struct net_device *ndev)
305 hdlc_device *hdlc = dev_to_hdlc (ndev);
306 const struct c4_priv *priv = hdlc->priv;
308 netif_stop_queue (ndev);
309 musycc_chan_down ((ci_t *) 0, priv->channum);
310 hdlc_close (ndev);
311 module_put (THIS_MODULE);
312 return 0;
316 static int
317 chan_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
319 return hdlc_ioctl (dev, ifr, cmd);
323 static int
324 chan_attach_noop (struct net_device *ndev, unsigned short foo_1, unsigned short foo_2)
326 return 0; /* our driver has nothing to do here, show's
327 * over, go home */
331 static struct net_device_stats *
332 chan_get_stats (struct net_device *ndev)
334 mch_t *ch;
335 struct net_device_stats *nstats;
336 struct sbecom_chan_stats *stats;
337 int channum;
340 struct c4_priv *priv;
342 priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
343 channum = priv->channum;
346 ch = c4_find_chan (channum);
347 if (ch == NULL)
348 return NULL;
350 nstats = &ndev->stats;
351 stats = &ch->s;
353 memset (nstats, 0, sizeof (struct net_device_stats));
354 nstats->rx_packets = stats->rx_packets;
355 nstats->tx_packets = stats->tx_packets;
356 nstats->rx_bytes = stats->rx_bytes;
357 nstats->tx_bytes = stats->tx_bytes;
358 nstats->rx_errors = stats->rx_length_errors +
359 stats->rx_over_errors +
360 stats->rx_crc_errors +
361 stats->rx_frame_errors +
362 stats->rx_fifo_errors +
363 stats->rx_missed_errors;
364 nstats->tx_errors = stats->tx_dropped +
365 stats->tx_aborted_errors +
366 stats->tx_fifo_errors;
367 nstats->rx_dropped = stats->rx_dropped;
368 nstats->tx_dropped = stats->tx_dropped;
370 nstats->rx_length_errors = stats->rx_length_errors;
371 nstats->rx_over_errors = stats->rx_over_errors;
372 nstats->rx_crc_errors = stats->rx_crc_errors;
373 nstats->rx_frame_errors = stats->rx_frame_errors;
374 nstats->rx_fifo_errors = stats->rx_fifo_errors;
375 nstats->rx_missed_errors = stats->rx_missed_errors;
377 nstats->tx_aborted_errors = stats->tx_aborted_errors;
378 nstats->tx_fifo_errors = stats->tx_fifo_errors;
380 return nstats;
384 static ci_t *
385 get_ci_by_dev (struct net_device *ndev)
387 return (ci_t *)(netdev_priv(ndev));
391 static int
392 c4_linux_xmit (struct sk_buff *skb, struct net_device *ndev)
394 const struct c4_priv *priv;
395 int rval;
397 hdlc_device *hdlc = dev_to_hdlc (ndev);
399 priv = hdlc->priv;
401 rval = musycc_start_xmit (priv->ci, priv->channum, skb);
402 return rval;
405 static const struct net_device_ops chan_ops = {
406 .ndo_open = chan_open,
407 .ndo_stop = chan_close,
408 .ndo_start_xmit = c4_linux_xmit,
409 .ndo_do_ioctl = chan_dev_ioctl,
410 .ndo_get_stats = chan_get_stats,
413 static struct net_device *
414 create_chan (struct net_device *ndev, ci_t *ci,
415 struct sbecom_chan_param *cp)
417 hdlc_device *hdlc;
418 struct net_device *dev;
419 hdw_info_t *hi;
420 int ret;
422 if (c4_find_chan (cp->channum))
423 return NULL; /* channel already exists */
426 struct c4_priv *priv;
428 /* allocate then fill in private data structure */
429 priv = OS_kmalloc (sizeof (struct c4_priv));
430 if (!priv)
432 pr_warning("%s: no memory for net_device !\n", ci->devname);
433 return NULL;
435 dev = alloc_hdlcdev (priv);
436 if (!dev)
438 pr_warning("%s: no memory for hdlc_device !\n", ci->devname);
439 OS_kfree (priv);
440 return NULL;
442 priv->ci = ci;
443 priv->channum = cp->channum;
446 hdlc = dev_to_hdlc (dev);
448 dev->base_addr = 0; /* not I/O mapped */
449 dev->irq = ndev->irq;
450 dev->type = ARPHRD_RAWHDLC;
451 *dev->name = 0; /* default ifconfig name = "hdlc" */
453 hi = (hdw_info_t *) ci->hdw_info;
454 if (hi->mfg_info_sts == EEPROM_OK)
456 switch (hi->promfmt)
458 case PROM_FORMAT_TYPE1:
459 memcpy (dev->dev_addr, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
460 break;
461 case PROM_FORMAT_TYPE2:
462 memcpy (dev->dev_addr, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
463 break;
464 default:
465 memset (dev->dev_addr, 0, 6);
466 break;
468 } else
470 memset (dev->dev_addr, 0, 6);
473 hdlc->xmit = c4_linux_xmit;
475 dev->netdev_ops = &chan_ops;
477 * The native hdlc stack calls this 'attach' routine during
478 * hdlc_raw_ioctl(), passing parameters for line encoding and parity.
479 * Since hdlc_raw_ioctl() stack does not interrogate whether an 'attach'
480 * routine is actually registered or not, we supply a dummy routine which
481 * does nothing (since encoding and parity are setup for our driver via a
482 * special configuration application).
485 hdlc->attach = chan_attach_noop;
487 rtnl_unlock (); /* needed due to Ioctl calling sequence */
488 ret = register_hdlc_device (dev);
489 /* NOTE: <stats> setting must occur AFTER registration in order to "take" */
490 dev->tx_queue_len = MAX_DEFAULT_IFQLEN;
492 rtnl_lock (); /* needed due to Ioctl calling sequence */
493 if (ret)
495 if (cxt1e1_log_level >= LOG_WARN)
496 pr_info("%s: create_chan[%d] registration error = %d.\n",
497 ci->devname, cp->channum, ret);
498 free_netdev (dev); /* cleanup */
499 return NULL; /* failed to register */
501 return dev;
505 /* the idea here is to get port information and pass it back (using pointer) */
506 static status_t
507 do_get_port (struct net_device *ndev, void *data)
509 int ret;
510 ci_t *ci; /* ci stands for card information */
511 struct sbecom_port_param pp;/* copy data to kernel land */
513 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
514 return -EFAULT;
515 if (pp.portnum >= MUSYCC_NPORTS)
516 return -EFAULT;
517 ci = get_ci_by_dev (ndev);
518 if (!ci)
519 return -EINVAL; /* get card info */
521 ret = mkret (c4_get_port (ci, pp.portnum));
522 if (ret)
523 return ret;
524 if (copy_to_user (data, &ci->port[pp.portnum].p,
525 sizeof (struct sbecom_port_param)))
526 return -EFAULT;
527 return 0;
530 /* this function copys the user data and then calls the real action function */
531 static status_t
532 do_set_port (struct net_device *ndev, void *data)
534 ci_t *ci; /* ci stands for card information */
535 struct sbecom_port_param pp;/* copy data to kernel land */
537 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
538 return -EFAULT;
539 if (pp.portnum >= MUSYCC_NPORTS)
540 return -EFAULT;
541 ci = get_ci_by_dev (ndev);
542 if (!ci)
543 return -EINVAL; /* get card info */
545 if (pp.portnum >= ci->max_port) /* sanity check */
546 return -ENXIO;
548 memcpy (&ci->port[pp.portnum].p, &pp, sizeof (struct sbecom_port_param));
549 return mkret (c4_set_port (ci, pp.portnum));
552 /* work the port loopback mode as per directed */
553 static status_t
554 do_port_loop (struct net_device *ndev, void *data)
556 struct sbecom_port_param pp;
557 ci_t *ci;
559 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
560 return -EFAULT;
561 ci = get_ci_by_dev (ndev);
562 if (!ci)
563 return -EINVAL;
564 return mkret (c4_loop_port (ci, pp.portnum, pp.port_mode));
567 /* set the specified register with the given value / or just read it */
568 static status_t
569 do_framer_rw (struct net_device *ndev, void *data)
571 struct sbecom_port_param pp;
572 ci_t *ci;
573 int ret;
575 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
576 return -EFAULT;
577 ci = get_ci_by_dev (ndev);
578 if (!ci)
579 return -EINVAL;
580 ret = mkret (c4_frame_rw (ci, &pp));
581 if (ret)
582 return ret;
583 if (copy_to_user (data, &pp, sizeof (struct sbecom_port_param)))
584 return -EFAULT;
585 return 0;
588 /* set the specified register with the given value / or just read it */
589 static status_t
590 do_pld_rw (struct net_device *ndev, void *data)
592 struct sbecom_port_param pp;
593 ci_t *ci;
594 int ret;
596 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
597 return -EFAULT;
598 ci = get_ci_by_dev (ndev);
599 if (!ci)
600 return -EINVAL;
601 ret = mkret (c4_pld_rw (ci, &pp));
602 if (ret)
603 return ret;
604 if (copy_to_user (data, &pp, sizeof (struct sbecom_port_param)))
605 return -EFAULT;
606 return 0;
609 /* set the specified register with the given value / or just read it */
610 static status_t
611 do_musycc_rw (struct net_device *ndev, void *data)
613 struct c4_musycc_param mp;
614 ci_t *ci;
615 int ret;
617 if (copy_from_user (&mp, data, sizeof (struct c4_musycc_param)))
618 return -EFAULT;
619 ci = get_ci_by_dev (ndev);
620 if (!ci)
621 return -EINVAL;
622 ret = mkret (c4_musycc_rw (ci, &mp));
623 if (ret)
624 return ret;
625 if (copy_to_user (data, &mp, sizeof (struct c4_musycc_param)))
626 return -EFAULT;
627 return 0;
630 static status_t
631 do_get_chan (struct net_device *ndev, void *data)
633 struct sbecom_chan_param cp;
634 int ret;
636 if (copy_from_user (&cp, data,
637 sizeof (struct sbecom_chan_param)))
638 return -EFAULT;
640 if ((ret = mkret (c4_get_chan (cp.channum, &cp))))
641 return ret;
643 if (copy_to_user (data, &cp, sizeof (struct sbecom_chan_param)))
644 return -EFAULT;
645 return 0;
648 static status_t
649 do_set_chan (struct net_device *ndev, void *data)
651 struct sbecom_chan_param cp;
652 int ret;
653 ci_t *ci;
655 if (copy_from_user (&cp, data, sizeof (struct sbecom_chan_param)))
656 return -EFAULT;
657 ci = get_ci_by_dev (ndev);
658 if (!ci)
659 return -EINVAL;
660 switch (ret = mkret (c4_set_chan (cp.channum, &cp)))
662 case 0:
663 return 0;
664 default:
665 return ret;
669 static status_t
670 do_create_chan (struct net_device *ndev, void *data)
672 ci_t *ci;
673 struct net_device *dev;
674 struct sbecom_chan_param cp;
675 int ret;
677 if (copy_from_user (&cp, data, sizeof (struct sbecom_chan_param)))
678 return -EFAULT;
679 ci = get_ci_by_dev (ndev);
680 if (!ci)
681 return -EINVAL;
682 dev = create_chan (ndev, ci, &cp);
683 if (!dev)
684 return -EBUSY;
685 ret = mkret (c4_new_chan (ci, cp.port, cp.channum, dev));
686 if (ret)
688 rtnl_unlock (); /* needed due to Ioctl calling sequence */
689 unregister_hdlc_device (dev);
690 rtnl_lock (); /* needed due to Ioctl calling sequence */
691 free_netdev (dev);
693 return ret;
696 static status_t
697 do_get_chan_stats (struct net_device *ndev, void *data)
699 struct c4_chan_stats_wrap ccs;
700 int ret;
702 if (copy_from_user (&ccs, data,
703 sizeof (struct c4_chan_stats_wrap)))
704 return -EFAULT;
705 switch (ret = mkret (c4_get_chan_stats (ccs.channum, &ccs.stats)))
707 case 0:
708 break;
709 default:
710 return ret;
712 if (copy_to_user (data, &ccs,
713 sizeof (struct c4_chan_stats_wrap)))
714 return -EFAULT;
715 return 0;
717 static status_t
718 do_set_loglevel (struct net_device *ndev, void *data)
720 unsigned int cxt1e1_log_level;
722 if (copy_from_user (&cxt1e1_log_level, data, sizeof (int)))
723 return -EFAULT;
724 sbecom_set_loglevel (cxt1e1_log_level);
725 return 0;
728 static status_t
729 do_deluser (struct net_device *ndev, int lockit)
731 if (ndev->flags & IFF_UP)
732 return -EBUSY;
735 ci_t *ci;
736 mch_t *ch;
737 const struct c4_priv *priv;
738 int channum;
740 priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
741 ci = priv->ci;
742 channum = priv->channum;
744 ch = c4_find_chan (channum);
745 if (ch == NULL)
746 return -ENOENT;
747 ch->user = NULL; /* will be freed, below */
750 if (lockit)
751 rtnl_unlock (); /* needed if Ioctl calling sequence */
752 unregister_hdlc_device (ndev);
753 if (lockit)
754 rtnl_lock (); /* needed if Ioctl calling sequence */
755 free_netdev (ndev);
756 return 0;
760 do_del_chan (struct net_device *musycc_dev, void *data)
762 struct sbecom_chan_param cp;
763 char buf[sizeof (CHANNAME) + 3];
764 struct net_device *dev;
765 int ret;
767 if (copy_from_user (&cp, data,
768 sizeof (struct sbecom_chan_param)))
769 return -EFAULT;
770 if (cp.channum > 999)
771 return -EINVAL;
772 snprintf (buf, sizeof(buf), CHANNAME "%d", cp.channum);
773 dev = __dev_get_by_name(&init_net, buf);
774 if (!dev)
775 return -ENODEV;
776 ret = do_deluser (dev, 1);
777 if (ret)
778 return ret;
779 return c4_del_chan (cp.channum);
781 int c4_reset_board (void *);
784 do_reset (struct net_device *musycc_dev, void *data)
786 const struct c4_priv *priv;
787 int i;
789 for (i = 0; i < 128; i++)
791 struct net_device *ndev;
792 char buf[sizeof (CHANNAME) + 3];
794 sprintf (buf, CHANNAME "%d", i);
795 ndev = __dev_get_by_name(&init_net, buf);
796 if (!ndev)
797 continue;
798 priv = dev_to_hdlc (ndev)->priv;
800 if ((unsigned long) (priv->ci) ==
801 (unsigned long) (netdev_priv(musycc_dev)))
803 ndev->flags &= ~IFF_UP;
804 netif_stop_queue (ndev);
805 do_deluser (ndev, 1);
808 return 0;
812 do_reset_chan_stats (struct net_device *musycc_dev, void *data)
814 struct sbecom_chan_param cp;
816 if (copy_from_user (&cp, data,
817 sizeof (struct sbecom_chan_param)))
818 return -EFAULT;
819 return mkret (c4_del_chan_stats (cp.channum));
822 static status_t
823 c4_ioctl (struct net_device *ndev, struct ifreq *ifr, int cmd)
825 ci_t *ci;
826 void *data;
827 int iocmd, iolen;
828 status_t ret;
829 static struct data
831 union
833 u_int8_t c;
834 u_int32_t i;
835 struct sbe_brd_info bip;
836 struct sbe_drv_info dip;
837 struct sbe_iid_info iip;
838 struct sbe_brd_addr bap;
839 struct sbecom_chan_stats stats;
840 struct sbecom_chan_param param;
841 struct temux_card_stats cards;
842 struct sbecom_card_param cardp;
843 struct sbecom_framer_param frp;
844 } u;
845 } arg;
848 if (!capable (CAP_SYS_ADMIN))
849 return -EPERM;
850 if (cmd != SIOCDEVPRIVATE + 15)
851 return -EINVAL;
852 if (!(ci = get_ci_by_dev (ndev)))
853 return -EINVAL;
854 if (ci->state != C_RUNNING)
855 return -ENODEV;
856 if (copy_from_user (&iocmd, ifr->ifr_data, sizeof (iocmd)))
857 return -EFAULT;
858 #if 0
859 if (copy_from_user (&len, ifr->ifr_data + sizeof (iocmd), sizeof (len)))
860 return -EFAULT;
861 #endif
863 #if 0
864 pr_info("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd,
865 _IOC_DIR (iocmd), _IOC_TYPE (iocmd), _IOC_NR (iocmd),
866 _IOC_SIZE (iocmd));
867 #endif
868 iolen = _IOC_SIZE (iocmd);
869 data = ifr->ifr_data + sizeof (iocmd);
870 if (copy_from_user (&arg, data, iolen))
871 return -EFAULT;
873 ret = 0;
874 switch (iocmd)
876 case SBE_IOC_PORT_GET:
877 //pr_info(">> SBE_IOC_PORT_GET Ioctl...\n");
878 ret = do_get_port (ndev, data);
879 break;
880 case SBE_IOC_PORT_SET:
881 //pr_info(">> SBE_IOC_PORT_SET Ioctl...\n");
882 ret = do_set_port (ndev, data);
883 break;
884 case SBE_IOC_CHAN_GET:
885 //pr_info(">> SBE_IOC_CHAN_GET Ioctl...\n");
886 ret = do_get_chan (ndev, data);
887 break;
888 case SBE_IOC_CHAN_SET:
889 //pr_info(">> SBE_IOC_CHAN_SET Ioctl...\n");
890 ret = do_set_chan (ndev, data);
891 break;
892 case C4_DEL_CHAN:
893 //pr_info(">> C4_DEL_CHAN Ioctl...\n");
894 ret = do_del_chan (ndev, data);
895 break;
896 case SBE_IOC_CHAN_NEW:
897 ret = do_create_chan (ndev, data);
898 break;
899 case SBE_IOC_CHAN_GET_STAT:
900 ret = do_get_chan_stats (ndev, data);
901 break;
902 case SBE_IOC_LOGLEVEL:
903 ret = do_set_loglevel (ndev, data);
904 break;
905 case SBE_IOC_RESET_DEV:
906 ret = do_reset (ndev, data);
907 break;
908 case SBE_IOC_CHAN_DEL_STAT:
909 ret = do_reset_chan_stats (ndev, data);
910 break;
911 case C4_LOOP_PORT:
912 ret = do_port_loop (ndev, data);
913 break;
914 case C4_RW_FRMR:
915 ret = do_framer_rw (ndev, data);
916 break;
917 case C4_RW_MSYC:
918 ret = do_musycc_rw (ndev, data);
919 break;
920 case C4_RW_PLD:
921 ret = do_pld_rw (ndev, data);
922 break;
923 case SBE_IOC_IID_GET:
924 ret = (iolen == sizeof (struct sbe_iid_info)) ? c4_get_iidinfo (ci, &arg.u.iip) : -EFAULT;
925 if (ret == 0) /* no error, copy data */
926 if (copy_to_user (data, &arg, iolen))
927 return -EFAULT;
928 break;
929 default:
930 //pr_info(">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd);
931 ret = -EINVAL;
932 break;
934 return mkret (ret);
937 static const struct net_device_ops c4_ops = {
938 .ndo_open = void_open,
939 .ndo_start_xmit = c4_linux_xmit,
940 .ndo_do_ioctl = c4_ioctl,
943 static void c4_setup(struct net_device *dev)
945 dev->type = ARPHRD_VOID;
946 dev->netdev_ops = &c4_ops;
949 struct net_device *__init
950 c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
951 int irq0, int irq1)
953 struct net_device *ndev;
954 ci_t *ci;
956 ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup);
957 if (!ndev)
959 pr_warning("%s: no memory for struct net_device !\n", hi->devname);
960 error_flag = ENOMEM;
961 return NULL;
963 ci = (ci_t *)(netdev_priv(ndev));
964 ndev->irq = irq0;
966 ci->hdw_info = hi;
967 ci->state = C_INIT; /* mark as hardware not available */
968 ci->next = c4_list;
969 c4_list = ci;
970 ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
972 if (!CI)
973 CI = ci; /* DEBUG, only board 0 usage */
975 strcpy (ci->devname, hi->devname);
976 ci->release = &pmcc4_OSSI_release[0];
978 /* tasklet */
979 #if defined(SBE_ISR_TASKLET)
980 tasklet_init (&ci->ci_musycc_isr_tasklet,
981 (void (*) (unsigned long)) musycc_intr_bh_tasklet,
982 (unsigned long) ci);
984 if (atomic_read (&ci->ci_musycc_isr_tasklet.count) == 0)
985 tasklet_disable_nosync (&ci->ci_musycc_isr_tasklet);
986 #elif defined(SBE_ISR_IMMEDIATE)
987 ci->ci_musycc_isr_tq.routine = (void *) (unsigned long) musycc_intr_bh_tasklet;
988 ci->ci_musycc_isr_tq.data = ci;
989 #endif
992 if (register_netdev (ndev) ||
993 (c4_init (ci, (u_char *) f0, (u_char *) f1) != SBE_DRVR_SUCCESS))
995 OS_kfree (netdev_priv(ndev));
996 OS_kfree (ndev);
997 error_flag = ENODEV;
998 return NULL;
1000 /*************************************************************
1001 * int request_irq(unsigned int irq,
1002 * void (*handler)(int, void *, struct pt_regs *),
1003 * unsigned long flags, const char *dev_name, void *dev_id);
1004 * wherein:
1005 * irq -> The interrupt number that is being requested.
1006 * handler -> Pointer to handling function being installed.
1007 * flags -> A bit mask of options related to interrupt management.
1008 * dev_name -> String used in /proc/interrupts to show owner of interrupt.
1009 * dev_id -> Pointer (for shared interrupt lines) to point to its own
1010 * private data area (to identify which device is interrupting).
1012 * extern void free_irq(unsigned int irq, void *dev_id);
1013 **************************************************************/
1015 if (request_irq (irq0, &c4_linux_interrupt,
1016 IRQF_SHARED,
1017 ndev->name, ndev))
1019 pr_warning("%s: MUSYCC could not get irq: %d\n", ndev->name, irq0);
1020 unregister_netdev (ndev);
1021 OS_kfree (netdev_priv(ndev));
1022 OS_kfree (ndev);
1023 error_flag = EIO;
1024 return NULL;
1026 #ifdef CONFIG_SBE_PMCC4_NCOMM
1027 if (request_irq (irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev))
1029 pr_warning("%s: EBUS could not get irq: %d\n", hi->devname, irq1);
1030 unregister_netdev (ndev);
1031 free_irq (irq0, ndev);
1032 OS_kfree (netdev_priv(ndev));
1033 OS_kfree (ndev);
1034 error_flag = EIO;
1035 return NULL;
1037 #endif
1039 /* setup board identification information */
1042 u_int32_t tmp;
1044 hdw_sn_get (hi, brdno); /* also sets PROM format type (promfmt)
1045 * for later usage */
1047 switch (hi->promfmt)
1049 case PROM_FORMAT_TYPE1:
1050 memcpy (ndev->dev_addr, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
1051 memcpy (&tmp, (FLD_TYPE1 *) (hi->mfg_info.pft1.Id), 4); /* unaligned data
1052 * acquisition */
1053 ci->brd_id = cpu_to_be32 (tmp);
1054 break;
1055 case PROM_FORMAT_TYPE2:
1056 memcpy (ndev->dev_addr, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
1057 memcpy (&tmp, (FLD_TYPE2 *) (hi->mfg_info.pft2.Id), 4); /* unaligned data
1058 * acquisition */
1059 ci->brd_id = cpu_to_be32 (tmp);
1060 break;
1061 default:
1062 ci->brd_id = 0;
1063 memset (ndev->dev_addr, 0, 6);
1064 break;
1067 #if 1
1068 sbeid_set_hdwbid (ci); /* requires bid to be preset */
1069 #else
1070 sbeid_set_bdtype (ci); /* requires hdw_bid to be preset */
1071 #endif
1075 #ifdef CONFIG_PROC_FS
1076 sbecom_proc_brd_init (ci);
1077 #endif
1078 #if defined(SBE_ISR_TASKLET)
1079 tasklet_enable (&ci->ci_musycc_isr_tasklet);
1080 #endif
1083 if ((error_flag = c4_init2 (ci)) != SBE_DRVR_SUCCESS)
1085 #ifdef CONFIG_PROC_FS
1086 sbecom_proc_brd_cleanup (ci);
1087 #endif
1088 unregister_netdev (ndev);
1089 free_irq (irq1, ndev);
1090 free_irq (irq0, ndev);
1091 OS_kfree (netdev_priv(ndev));
1092 OS_kfree (ndev);
1093 return NULL; /* failure, error_flag is set */
1095 return ndev;
1098 static int __init
1099 c4_mod_init (void)
1101 int rtn;
1103 pr_warning("%s\n", pmcc4_OSSI_release);
1104 if ((rtn = c4hw_attach_all ()))
1105 return -rtn; /* installation failure - see system log */
1107 /* housekeeping notifications */
1108 if (cxt1e1_log_level != log_level_default)
1109 pr_info("NOTE: driver parameter <cxt1e1_log_level> changed from default %d to %d.\n",
1110 log_level_default, cxt1e1_log_level);
1111 if (cxt1e1_max_mru != max_mru_default)
1112 pr_info("NOTE: driver parameter <cxt1e1_max_mru> changed from default %d to %d.\n",
1113 max_mru_default, cxt1e1_max_mru);
1114 if (cxt1e1_max_mtu != max_mtu_default)
1115 pr_info("NOTE: driver parameter <cxt1e1_max_mtu> changed from default %d to %d.\n",
1116 max_mtu_default, cxt1e1_max_mtu);
1117 if (max_rxdesc_used != max_rxdesc_default)
1119 if (max_rxdesc_used > 2000)
1120 max_rxdesc_used = 2000; /* out-of-bounds reset */
1121 pr_info("NOTE: driver parameter <max_rxdesc_used> changed from default %d to %d.\n",
1122 max_rxdesc_default, max_rxdesc_used);
1124 if (max_txdesc_used != max_txdesc_default)
1126 if (max_txdesc_used > 1000)
1127 max_txdesc_used = 1000; /* out-of-bounds reset */
1128 pr_info("NOTE: driver parameter <max_txdesc_used> changed from default %d to %d.\n",
1129 max_txdesc_default, max_txdesc_used);
1131 return 0; /* installation success */
1136 * find any still allocated hdlc registrations and unregister via call to
1137 * do_deluser()
1140 static void __exit
1141 cleanup_hdlc (void)
1143 hdw_info_t *hi;
1144 ci_t *ci;
1145 struct net_device *ndev;
1146 int i, j, k;
1148 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
1150 if (hi->ndev) /* a board has been attached */
1152 ci = (ci_t *)(netdev_priv(hi->ndev));
1153 for (j = 0; j < ci->max_port; j++)
1154 for (k = 0; k < MUSYCC_NCHANS; k++)
1155 if ((ndev = ci->port[j].chan[k]->user))
1157 do_deluser (ndev, 0);
1164 static void __exit
1165 c4_mod_remove (void)
1167 cleanup_hdlc(); /* delete any missed channels */
1168 cleanup_devs();
1169 c4_cleanup();
1170 cleanup_ioremap();
1171 pr_info("SBE - driver removed.\n");
1174 module_init (c4_mod_init);
1175 module_exit (c4_mod_remove);
1177 MODULE_AUTHOR ("SBE Technical Services <support@sbei.com>");
1178 MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module");
1179 #ifdef MODULE_LICENSE
1180 MODULE_LICENSE ("GPL");
1181 #endif
1183 /*** End-of-File ***/