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