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