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