]> Pileus Git - ~andy/linux/blob - drivers/staging/cxt1e1/linux.c
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
[~andy/linux] / drivers / staging / cxt1e1 / linux.c
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 */
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);
66
67 #ifdef CONFIG_SBE_PMCC4_NCOMM
68 irqreturn_t c4_ebus_intr_th_handler (void *);
69
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 *);
83
84 extern char pmcc4_OSSI_release[];
85 extern ci_t *CI;
86 extern struct s_hdw_info hdw_info[];
87
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
94
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 *);
100
101 #else
102 #define V7(x) x
103 #endif
104
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);
109
110 int         cxt1e1_max_mru = MUSYCC_MRU;
111 int         max_mru_default = MUSYCC_MRU;
112 module_param(cxt1e1_max_mru, int, 0444);
113
114 int         cxt1e1_max_mtu = MUSYCC_MTU;
115 int         max_mtu_default = MUSYCC_MTU;
116 module_param(cxt1e1_max_mtu, int, 0444);
117
118 int         max_txdesc_used = MUSYCC_TXDESC_MIN;
119 int         max_txdesc_default = MUSYCC_TXDESC_MIN;
120 module_param(max_txdesc_used, int, 0444);
121
122 int         max_rxdesc_used = MUSYCC_RXDESC_MIN;
123 int         max_rxdesc_default = MUSYCC_RXDESC_MIN;
124 module_param(max_rxdesc_used, int, 0444);
125
126 /****************************************************************************/
127 /****************************************************************************/
128 /****************************************************************************/
129
130 void       *
131 getuserbychan (int channum)
132 {
133     mch_t      *ch;
134
135     ch = c4_find_chan (channum);
136     return ch ? ch->user : NULL;
137 }
138
139
140 char       *
141 get_hdlc_name (hdlc_device *hdlc)
142 {
143     struct c4_priv *priv = hdlc->priv;
144     struct net_device *dev = getuserbychan (priv->channum);
145
146     return dev->name;
147 }
148
149
150 static      status_t
151 mkret (int bsd)
152 {
153     if (bsd > 0)
154         return -bsd;
155     else
156         return bsd;
157 }
158
159 /***************************************************************************/
160 #include <linux/workqueue.h>
161
162 /***
163  * One workqueue (wq) per port (since musycc allows simultaneous group
164  * commands), with individual data for each channel:
165  *
166  *   mpi_t -> struct workqueue_struct *wq_port;  (dynamically allocated using
167  *                                               create_workqueue())
168  *
169  * With work structure (work) statically allocated for each channel:
170  *
171  *   mch_t -> struct work_struct ch_work;  (statically allocated using ???)
172  *
173  ***/
174
175
176 /*
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.
180  */
181 void
182 c4_wk_chan_restart (mch_t *ch)
183 {
184     mpi_t      *pi = ch->up;
185
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
190
191     /* create new entry w/in workqueue for this channel and let'er rip */
192
193     /** queue_work (struct workqueue_struct *queue,
194      **             struct work_struct *work);
195      **/
196     queue_work (pi->wq_port, &ch->ch_work);
197 }
198
199 status_t
200 c4_wk_chan_init (mpi_t *pi, mch_t *ch)
201 {
202     /*
203      * this will be used to restart a stopped channel
204      */
205
206     /** INIT_WORK (struct work_struct *work,
207      **            void (*function)(void *),
208      **            void *data);
209      **/
210     INIT_WORK(&ch->ch_work, (void *)musycc_wq_chan_restart);
211     return 0;                       /* success */
212 }
213
214 status_t
215 c4_wq_port_init (mpi_t *pi)
216 {
217
218     char        name[16], *np;  /* NOTE: name of the queue limited by system
219                                  * to 10 characters */
220
221     if (pi->wq_port)
222         return 0;                   /* already initialized */
223
224     np = name;
225     memset (name, 0, 16);
226     sprintf (np, "%s%d", pi->up->devname, pi->portnum); /* IE pmcc4-01) */
227
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 */
235 }
236
237 void
238 c4_wq_port_cleanup (mpi_t *pi)
239 {
240     /*
241      * PORT POINT: cannot call this if WQ is statically allocated w/in
242      * structure since it calls kfree(wq);
243      */
244     if (pi->wq_port)
245     {
246         destroy_workqueue (pi->wq_port);        /* this also calls
247                                                  * flush_workqueue() */
248         pi->wq_port = NULL;
249     }
250 }
251
252 /***************************************************************************/
253
254 irqreturn_t
255 c4_linux_interrupt (int irq, void *dev_instance)
256 {
257     struct net_device *ndev = dev_instance;
258
259     return musycc_intr_th_handler(netdev_priv(ndev));
260 }
261
262
263 #ifdef CONFIG_SBE_PMCC4_NCOMM
264 irqreturn_t
265 c4_ebus_interrupt (int irq, void *dev_instance)
266 {
267     struct net_device *ndev = dev_instance;
268
269     return c4_ebus_intr_th_handler(netdev_priv(ndev));
270 }
271 #endif
272
273
274 static int
275 void_open (struct net_device *ndev)
276 {
277     pr_info("%s: trying to open master device !\n", ndev->name);
278     return -1;
279 }
280
281
282 static int
283 chan_open (struct net_device *ndev)
284 {
285     hdlc_device *hdlc = dev_to_hdlc (ndev);
286     const struct c4_priv *priv = hdlc->priv;
287     int         ret;
288
289     if ((ret = hdlc_open (ndev)))
290     {
291         pr_info("hdlc_open failure, err %d.\n", ret);
292         return ret;
293     }
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 */
299 }
300
301
302 static int
303 chan_close (struct net_device *ndev)
304 {
305     hdlc_device *hdlc = dev_to_hdlc (ndev);
306     const struct c4_priv *priv = hdlc->priv;
307
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;
313 }
314
315
316 static int
317 chan_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
318 {
319     return hdlc_ioctl (dev, ifr, cmd);
320 }
321
322
323 static int
324 chan_attach_noop (struct net_device *ndev, unsigned short foo_1, unsigned short foo_2)
325 {
326     return 0;                   /* our driver has nothing to do here, show's
327                                  * over, go home */
328 }
329
330
331 static struct net_device_stats *
332 chan_get_stats (struct net_device *ndev)
333 {
334     mch_t      *ch;
335     struct net_device_stats *nstats;
336     struct sbecom_chan_stats *stats;
337     int         channum;
338
339     {
340         struct c4_priv *priv;
341
342         priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
343         channum = priv->channum;
344     }
345
346     ch = c4_find_chan (channum);
347     if (ch == NULL)
348         return NULL;
349
350     nstats = &ndev->stats;
351     stats = &ch->s;
352
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;
369
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;
376
377     nstats->tx_aborted_errors = stats->tx_aborted_errors;
378     nstats->tx_fifo_errors = stats->tx_fifo_errors;
379
380     return nstats;
381 }
382
383
384 static ci_t *
385 get_ci_by_dev (struct net_device *ndev)
386 {
387     return (ci_t *)(netdev_priv(ndev));
388 }
389
390
391 static int
392 c4_linux_xmit (struct sk_buff *skb, struct net_device *ndev)
393 {
394     const struct c4_priv *priv;
395     int         rval;
396
397     hdlc_device *hdlc = dev_to_hdlc (ndev);
398
399     priv = hdlc->priv;
400
401     rval = musycc_start_xmit (priv->ci, priv->channum, skb);
402     return rval;
403 }
404
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,
411 };
412
413 static struct net_device *
414 create_chan (struct net_device *ndev, ci_t *ci,
415              struct sbecom_chan_param *cp)
416 {
417     hdlc_device *hdlc;
418     struct net_device *dev;
419     hdw_info_t *hi;
420     int         ret;
421
422     if (c4_find_chan (cp->channum))
423         return NULL;                   /* channel already exists */
424
425     {
426         struct c4_priv *priv;
427
428         /* allocate then fill in private data structure */
429         priv = OS_kmalloc (sizeof (struct c4_priv));
430         if (!priv)
431         {
432             pr_warning("%s: no memory for net_device !\n", ci->devname);
433             return NULL;
434         }
435         dev = alloc_hdlcdev (priv);
436         if (!dev)
437         {
438             pr_warning("%s: no memory for hdlc_device !\n", ci->devname);
439             OS_kfree (priv);
440             return NULL;
441         }
442         priv->ci = ci;
443         priv->channum = cp->channum;
444     }
445
446     hdlc = dev_to_hdlc (dev);
447
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" */
452
453     hi = (hdw_info_t *) ci->hdw_info;
454     if (hi->mfg_info_sts == EEPROM_OK)
455     {
456         switch (hi->promfmt)
457         {
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;
467         }
468     } else
469     {
470         memset (dev->dev_addr, 0, 6);
471     }
472
473     hdlc->xmit = c4_linux_xmit;
474
475     dev->netdev_ops = &chan_ops;
476     /*
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).
483      */
484
485     hdlc->attach = chan_attach_noop;
486
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;
491
492     rtnl_lock ();                   /* needed due to Ioctl calling sequence */
493     if (ret)
494     {
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 */
500     }
501     return dev;
502 }
503
504
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)
508 {
509     int         ret;
510     ci_t       *ci;             /* ci stands for card information */
511     struct sbecom_port_param pp;/* copy data to kernel land */
512
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 */
520
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;
528 }
529
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)
533 {
534     ci_t       *ci;             /* ci stands for card information */
535     struct sbecom_port_param pp;/* copy data to kernel land */
536
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 */
544
545     if (pp.portnum >= ci->max_port) /* sanity check */
546         return -ENXIO;
547
548     memcpy (&ci->port[pp.portnum].p, &pp, sizeof (struct sbecom_port_param));
549     return mkret (c4_set_port (ci, pp.portnum));
550 }
551
552 /* work the port loopback mode as per directed */
553 static      status_t
554 do_port_loop (struct net_device *ndev, void *data)
555 {
556     struct sbecom_port_param pp;
557     ci_t       *ci;
558
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));
565 }
566
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)
570 {
571     struct sbecom_port_param pp;
572     ci_t       *ci;
573     int         ret;
574
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;
586 }
587
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)
591 {
592     struct sbecom_port_param pp;
593     ci_t       *ci;
594     int         ret;
595
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;
607 }
608
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)
612 {
613     struct c4_musycc_param mp;
614     ci_t       *ci;
615     int         ret;
616
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;
628 }
629
630 static      status_t
631 do_get_chan (struct net_device *ndev, void *data)
632 {
633     struct sbecom_chan_param cp;
634     int         ret;
635
636     if (copy_from_user (&cp, data,
637                         sizeof (struct sbecom_chan_param)))
638         return -EFAULT;
639
640     if ((ret = mkret (c4_get_chan (cp.channum, &cp))))
641         return ret;
642
643     if (copy_to_user (data, &cp, sizeof (struct sbecom_chan_param)))
644         return -EFAULT;
645     return 0;
646 }
647
648 static      status_t
649 do_set_chan (struct net_device *ndev, void *data)
650 {
651     struct sbecom_chan_param cp;
652     int         ret;
653     ci_t       *ci;
654
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)))
661     {
662     case 0:
663         return 0;
664     default:
665         return ret;
666     }
667 }
668
669 static      status_t
670 do_create_chan (struct net_device *ndev, void *data)
671 {
672     ci_t       *ci;
673     struct net_device *dev;
674     struct sbecom_chan_param cp;
675     int         ret;
676
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)
687     {
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);
692     }
693     return ret;
694 }
695
696 static      status_t
697 do_get_chan_stats (struct net_device *ndev, void *data)
698 {
699     struct c4_chan_stats_wrap ccs;
700     int         ret;
701
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)))
706     {
707     case 0:
708         break;
709     default:
710         return ret;
711     }
712     if (copy_to_user (data, &ccs,
713                       sizeof (struct c4_chan_stats_wrap)))
714         return -EFAULT;
715     return 0;
716 }
717 static      status_t
718 do_set_loglevel (struct net_device *ndev, void *data)
719 {
720     unsigned int cxt1e1_log_level;
721
722     if (copy_from_user (&cxt1e1_log_level, data, sizeof (int)))
723         return -EFAULT;
724     sbecom_set_loglevel (cxt1e1_log_level);
725     return 0;
726 }
727
728 static      status_t
729 do_deluser (struct net_device *ndev, int lockit)
730 {
731     if (ndev->flags & IFF_UP)
732         return -EBUSY;
733
734     {
735         ci_t       *ci;
736         mch_t      *ch;
737         const struct c4_priv *priv;
738         int         channum;
739
740         priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
741         ci = priv->ci;
742         channum = priv->channum;
743
744         ch = c4_find_chan (channum);
745         if (ch == NULL)
746             return -ENOENT;
747         ch->user = NULL;        /* will be freed, below */
748     }
749
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;
757 }
758
759 int
760 do_del_chan (struct net_device *musycc_dev, void *data)
761 {
762     struct sbecom_chan_param cp;
763     char        buf[sizeof (CHANNAME) + 3];
764     struct net_device *dev;
765     int         ret;
766
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);
780 }
781 int         c4_reset_board (void *);
782
783 int
784 do_reset (struct net_device *musycc_dev, void *data)
785 {
786     const struct c4_priv *priv;
787     int         i;
788
789     for (i = 0; i < 128; i++)
790     {
791         struct net_device *ndev;
792         char        buf[sizeof (CHANNAME) + 3];
793
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;
799
800         if ((unsigned long) (priv->ci) ==
801             (unsigned long) (netdev_priv(musycc_dev)))
802         {
803             ndev->flags &= ~IFF_UP;
804             netif_stop_queue (ndev);
805             do_deluser (ndev, 1);
806         }
807     }
808     return 0;
809 }
810
811 int
812 do_reset_chan_stats (struct net_device *musycc_dev, void *data)
813 {
814     struct sbecom_chan_param cp;
815
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));
820 }
821
822 static      status_t
823 c4_ioctl (struct net_device *ndev, struct ifreq *ifr, int cmd)
824 {
825     ci_t       *ci;
826     void       *data;
827     int         iocmd, iolen;
828     status_t    ret;
829     static struct data
830     {
831         union
832         {
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;
846
847
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
862
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     if (iolen > sizeof(arg))
870         return -EFAULT;
871     data = ifr->ifr_data + sizeof (iocmd);
872     if (copy_from_user (&arg, data, iolen))
873         return -EFAULT;
874
875     ret = 0;
876     switch (iocmd)
877     {
878     case SBE_IOC_PORT_GET:
879         //pr_info(">> SBE_IOC_PORT_GET Ioctl...\n");
880         ret = do_get_port (ndev, data);
881         break;
882     case SBE_IOC_PORT_SET:
883         //pr_info(">> SBE_IOC_PORT_SET Ioctl...\n");
884         ret = do_set_port (ndev, data);
885         break;
886     case SBE_IOC_CHAN_GET:
887         //pr_info(">> SBE_IOC_CHAN_GET Ioctl...\n");
888         ret = do_get_chan (ndev, data);
889         break;
890     case SBE_IOC_CHAN_SET:
891         //pr_info(">> SBE_IOC_CHAN_SET Ioctl...\n");
892         ret = do_set_chan (ndev, data);
893         break;
894     case C4_DEL_CHAN:
895         //pr_info(">> C4_DEL_CHAN Ioctl...\n");
896         ret = do_del_chan (ndev, data);
897         break;
898     case SBE_IOC_CHAN_NEW:
899         ret = do_create_chan (ndev, data);
900         break;
901     case SBE_IOC_CHAN_GET_STAT:
902         ret = do_get_chan_stats (ndev, data);
903         break;
904     case SBE_IOC_LOGLEVEL:
905         ret = do_set_loglevel (ndev, data);
906         break;
907     case SBE_IOC_RESET_DEV:
908         ret = do_reset (ndev, data);
909         break;
910     case SBE_IOC_CHAN_DEL_STAT:
911         ret = do_reset_chan_stats (ndev, data);
912         break;
913     case C4_LOOP_PORT:
914         ret = do_port_loop (ndev, data);
915         break;
916     case C4_RW_FRMR:
917         ret = do_framer_rw (ndev, data);
918         break;
919     case C4_RW_MSYC:
920         ret = do_musycc_rw (ndev, data);
921         break;
922     case C4_RW_PLD:
923         ret = do_pld_rw (ndev, data);
924         break;
925     case SBE_IOC_IID_GET:
926         ret = (iolen == sizeof (struct sbe_iid_info)) ? c4_get_iidinfo (ci, &arg.u.iip) : -EFAULT;
927         if (ret == 0)               /* no error, copy data */
928             if (copy_to_user (data, &arg, iolen))
929                 return -EFAULT;
930         break;
931     default:
932         //pr_info(">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd);
933         ret = -EINVAL;
934         break;
935     }
936     return mkret (ret);
937 }
938
939 static const struct net_device_ops c4_ops = {
940        .ndo_open       = void_open,
941        .ndo_start_xmit = c4_linux_xmit,
942        .ndo_do_ioctl   = c4_ioctl,
943 };
944
945 static void c4_setup(struct net_device *dev)
946 {
947        dev->type = ARPHRD_VOID;
948        dev->netdev_ops = &c4_ops;
949 }
950
951 struct net_device *__init
952 c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
953             int irq0, int irq1)
954 {
955     struct net_device *ndev;
956     ci_t       *ci;
957
958     ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup);
959     if (!ndev)
960     {
961         pr_warning("%s: no memory for struct net_device !\n", hi->devname);
962         error_flag = ENOMEM;
963         return NULL;
964     }
965     ci = (ci_t *)(netdev_priv(ndev));
966     ndev->irq = irq0;
967
968     ci->hdw_info = hi;
969     ci->state = C_INIT;         /* mark as hardware not available */
970     ci->next = c4_list;
971     c4_list = ci;
972     ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
973
974     if (!CI)
975         CI = ci;                    /* DEBUG, only board 0 usage */
976
977     strcpy (ci->devname, hi->devname);
978     ci->release = &pmcc4_OSSI_release[0];
979
980     /* tasklet */
981 #if defined(SBE_ISR_TASKLET)
982     tasklet_init (&ci->ci_musycc_isr_tasklet,
983                   (void (*) (unsigned long)) musycc_intr_bh_tasklet,
984                   (unsigned long) ci);
985
986     if (atomic_read (&ci->ci_musycc_isr_tasklet.count) == 0)
987         tasklet_disable_nosync (&ci->ci_musycc_isr_tasklet);
988 #elif defined(SBE_ISR_IMMEDIATE)
989     ci->ci_musycc_isr_tq.routine = (void *) (unsigned long) musycc_intr_bh_tasklet;
990     ci->ci_musycc_isr_tq.data = ci;
991 #endif
992
993
994     if (register_netdev (ndev) ||
995         (c4_init (ci, (u_char *) f0, (u_char *) f1) != SBE_DRVR_SUCCESS))
996     {
997         OS_kfree (netdev_priv(ndev));
998         OS_kfree (ndev);
999         error_flag = ENODEV;
1000         return NULL;
1001     }
1002     /*************************************************************
1003      *  int request_irq(unsigned int irq,
1004      *                  void (*handler)(int, void *, struct pt_regs *),
1005      *                  unsigned long flags, const char *dev_name, void *dev_id);
1006      *  wherein:
1007      *  irq      -> The interrupt number that is being requested.
1008      *  handler  -> Pointer to handling function being installed.
1009      *  flags    -> A bit mask of options related to interrupt management.
1010      *  dev_name -> String used in /proc/interrupts to show owner of interrupt.
1011      *  dev_id   -> Pointer (for shared interrupt lines) to point to its own
1012      *              private data area (to identify which device is interrupting).
1013      *
1014      *  extern void free_irq(unsigned int irq, void *dev_id);
1015      **************************************************************/
1016
1017     if (request_irq (irq0, &c4_linux_interrupt,
1018                      IRQF_SHARED,
1019                      ndev->name, ndev))
1020     {
1021         pr_warning("%s: MUSYCC could not get irq: %d\n", ndev->name, irq0);
1022         unregister_netdev (ndev);
1023         OS_kfree (netdev_priv(ndev));
1024         OS_kfree (ndev);
1025         error_flag = EIO;
1026         return NULL;
1027     }
1028 #ifdef CONFIG_SBE_PMCC4_NCOMM
1029     if (request_irq (irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev))
1030     {
1031         pr_warning("%s: EBUS could not get irq: %d\n", hi->devname, irq1);
1032         unregister_netdev (ndev);
1033         free_irq (irq0, ndev);
1034         OS_kfree (netdev_priv(ndev));
1035         OS_kfree (ndev);
1036         error_flag = EIO;
1037         return NULL;
1038     }
1039 #endif
1040
1041     /* setup board identification information */
1042
1043     {
1044         u_int32_t   tmp;
1045
1046         hdw_sn_get (hi, brdno);     /* also sets PROM format type (promfmt)
1047                                      * for later usage */
1048
1049         switch (hi->promfmt)
1050         {
1051         case PROM_FORMAT_TYPE1:
1052             memcpy (ndev->dev_addr, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
1053             memcpy (&tmp, (FLD_TYPE1 *) (hi->mfg_info.pft1.Id), 4);     /* unaligned data
1054                                                                          * acquisition */
1055             ci->brd_id = cpu_to_be32 (tmp);
1056             break;
1057         case PROM_FORMAT_TYPE2:
1058             memcpy (ndev->dev_addr, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
1059             memcpy (&tmp, (FLD_TYPE2 *) (hi->mfg_info.pft2.Id), 4);     /* unaligned data
1060                                                                          * acquisition */
1061             ci->brd_id = cpu_to_be32 (tmp);
1062             break;
1063         default:
1064             ci->brd_id = 0;
1065             memset (ndev->dev_addr, 0, 6);
1066             break;
1067         }
1068
1069 #if 1
1070         sbeid_set_hdwbid (ci);      /* requires bid to be preset */
1071 #else
1072         sbeid_set_bdtype (ci);      /* requires hdw_bid to be preset */
1073 #endif
1074
1075     }
1076
1077 #ifdef CONFIG_PROC_FS
1078     sbecom_proc_brd_init (ci);
1079 #endif
1080 #if defined(SBE_ISR_TASKLET)
1081     tasklet_enable (&ci->ci_musycc_isr_tasklet);
1082 #endif
1083
1084
1085     if ((error_flag = c4_init2 (ci)) != SBE_DRVR_SUCCESS)
1086     {
1087 #ifdef CONFIG_PROC_FS
1088         sbecom_proc_brd_cleanup (ci);
1089 #endif
1090         unregister_netdev (ndev);
1091         free_irq (irq1, ndev);
1092         free_irq (irq0, ndev);
1093         OS_kfree (netdev_priv(ndev));
1094         OS_kfree (ndev);
1095         return NULL;            /* failure, error_flag is set */
1096     }
1097     return ndev;
1098 }
1099
1100 static int  __init
1101 c4_mod_init (void)
1102 {
1103     int         rtn;
1104
1105     pr_warning("%s\n", pmcc4_OSSI_release);
1106     if ((rtn = c4hw_attach_all ()))
1107         return -rtn;                /* installation failure - see system log */
1108
1109     /* housekeeping notifications */
1110     if (cxt1e1_log_level != log_level_default)
1111         pr_info("NOTE: driver parameter <cxt1e1_log_level> changed from default %d to %d.\n",
1112                 log_level_default, cxt1e1_log_level);
1113        if (cxt1e1_max_mru != max_mru_default)
1114                pr_info("NOTE: driver parameter <cxt1e1_max_mru> changed from default %d to %d.\n",
1115                                max_mru_default, cxt1e1_max_mru);
1116        if (cxt1e1_max_mtu != max_mtu_default)
1117                pr_info("NOTE: driver parameter <cxt1e1_max_mtu> changed from default %d to %d.\n",
1118                                max_mtu_default, cxt1e1_max_mtu);
1119     if (max_rxdesc_used != max_rxdesc_default)
1120     {
1121         if (max_rxdesc_used > 2000)
1122             max_rxdesc_used = 2000; /* out-of-bounds reset */
1123         pr_info("NOTE: driver parameter <max_rxdesc_used> changed from default %d to %d.\n",
1124                 max_rxdesc_default, max_rxdesc_used);
1125     }
1126     if (max_txdesc_used != max_txdesc_default)
1127     {
1128         if (max_txdesc_used > 1000)
1129             max_txdesc_used = 1000; /* out-of-bounds reset */
1130         pr_info("NOTE: driver parameter <max_txdesc_used> changed from default %d to %d.\n",
1131                 max_txdesc_default, max_txdesc_used);
1132     }
1133     return 0;                       /* installation success */
1134 }
1135
1136
1137  /*
1138   * find any still allocated hdlc registrations and unregister via call to
1139   * do_deluser()
1140   */
1141
1142 static void __exit
1143 cleanup_hdlc (void)
1144 {
1145     hdw_info_t *hi;
1146     ci_t       *ci;
1147     struct net_device *ndev;
1148     int         i, j, k;
1149
1150     for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
1151     {
1152         if (hi->ndev)               /* a board has been attached */
1153         {
1154             ci = (ci_t *)(netdev_priv(hi->ndev));
1155             for (j = 0; j < ci->max_port; j++)
1156                 for (k = 0; k < MUSYCC_NCHANS; k++)
1157                     if ((ndev = ci->port[j].chan[k]->user))
1158                     {
1159                         do_deluser (ndev, 0);
1160                     }
1161         }
1162     }
1163 }
1164
1165
1166 static void __exit
1167 c4_mod_remove (void)
1168 {
1169         cleanup_hdlc();            /* delete any missed channels */
1170         cleanup_devs();
1171         c4_cleanup();
1172         cleanup_ioremap();
1173         pr_info("SBE - driver removed.\n");
1174 }
1175
1176 module_init (c4_mod_init);
1177 module_exit (c4_mod_remove);
1178
1179 MODULE_AUTHOR ("SBE Technical Services <support@sbei.com>");
1180 MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module");
1181 #ifdef MODULE_LICENSE
1182 MODULE_LICENSE ("GPL");
1183 #endif
1184
1185 /***  End-of-File  ***/