1 /* Copyright (C) 2007-2008 One Stop Systems
2 * Copyright (C) 2003-2006 SBE, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 #include <linux/types.h>
18 #include <linux/netdevice.h>
19 #include <linux/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"
29 #include "pmcc4_ioctls.h"
30 #include "pmcc4_private.h"
33 /*****************************************************************************************
34 * Error out early if we have compiler trouble.
36 * (This section is included from the kernel's init/main.c as a friendly
37 * spiderman recommendation...)
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.
44 #if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
45 #error Sorry, your GCC is too old. It builds incorrect kernels.
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.
52 /*****************************************************************************************/
54 #ifdef SBE_INCLUDE_SYMBOLS
60 #define CHANNAME "hdlc"
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);
72 #ifdef CONFIG_SBE_PMCC4_NCOMM
73 irqreturn_t
c4_ebus_intr_th_handler (void *);
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 *);
89 extern char pmcc4_OSSI_release
[];
91 extern struct s_hdw_info hdw_info
[];
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)
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
*);
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);
115 int max_mru
= MUSYCC_MRU
;
116 int max_mru_default
= MUSYCC_MRU
;
117 module_param(max_mru
, int, 0444);
119 int max_mtu
= MUSYCC_MTU
;
120 int max_mtu_default
= MUSYCC_MTU
;
121 module_param(max_mtu
, int, 0444);
123 int max_txdesc_used
= MUSYCC_TXDESC_MIN
;
124 int max_txdesc_default
= MUSYCC_TXDESC_MIN
;
125 module_param(max_txdesc_used
, int, 0444);
127 int max_rxdesc_used
= MUSYCC_RXDESC_MIN
;
128 int max_rxdesc_default
= MUSYCC_RXDESC_MIN
;
129 module_param(max_rxdesc_used
, int, 0444);
131 /****************************************************************************/
132 /****************************************************************************/
133 /****************************************************************************/
136 getuserbychan (int channum
)
140 ch
= c4_find_chan (channum
);
141 return ch
? ch
->user
: 0;
145 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
146 #define DEV_TO_PRIV(dev) ( * (struct c4_priv **) ((hdlc_device*)(dev)+1))
150 get_hdlc_name (hdlc_device
* hdlc
)
152 struct c4_priv
*priv
= hdlc
->priv
;
153 struct net_device
*dev
= getuserbychan (priv
->channum
);
169 /***************************************************************************/
170 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
171 #include <linux/workqueue.h>
174 * One workqueue (wq) per port (since musycc allows simultaneous group
175 * commands), with individual data for each channel:
177 * mpi_t -> struct workqueue_struct *wq_port; (dynamically allocated using
178 * create_workqueue())
180 * With work structure (work) statically allocated for each channel:
182 * mch_t -> struct work_struct ch_work; (statically allocated using ???)
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.
193 c4_wk_chan_restart (mch_t
* ch
)
197 #ifdef RLD_RESTART_DEBUG
198 pr_info(">> %s: queueing Port %d Chan %d, mch_t @ %p\n",
199 __func__
, pi
->portnum
, ch
->channum
, ch
);
202 /* create new entry w/in workqueue for this channel and let'er rip */
204 /** queue_work (struct workqueue_struct *queue,
205 ** struct work_struct *work);
207 queue_work (pi
->wq_port
, &ch
->ch_work
);
211 c4_wk_chan_init (mpi_t
* pi
, mch_t
* ch
)
214 * this will be used to restart a stopped channel
217 /** INIT_WORK (struct work_struct *work,
218 ** void (*function)(void *),
221 INIT_WORK(&ch
->ch_work
, (void *)musycc_wq_chan_restart
);
222 return 0; /* success */
226 c4_wq_port_init (mpi_t
* pi
)
229 char name
[16], *np
; /* NOTE: name of the queue limited by system
230 * to 10 characters */
233 return 0; /* already initialized */
236 memset (name
, 0, 16);
237 sprintf (np
, "%s%d", pi
->up
->devname
, pi
->portnum
); /* IE pmcc4-01) */
239 #ifdef RLD_RESTART_DEBUG
240 pr_info(">> %s: creating workqueue <%s> for Port %d.\n",
241 __func__
, name
, pi
->portnum
); /* RLD DEBUG */
243 if (!(pi
->wq_port
= create_singlethread_workqueue (name
)))
245 return 0; /* success */
249 c4_wq_port_cleanup (mpi_t
* pi
)
252 * PORT POINT: cannot call this if WQ is statically allocated w/in
253 * structure since it calls kfree(wq);
257 destroy_workqueue (pi
->wq_port
); /* this also calls
258 * flush_workqueue() */
264 /***************************************************************************/
267 c4_linux_interrupt (int irq
, void *dev_instance
)
269 struct net_device
*ndev
= dev_instance
;
271 return musycc_intr_th_handler(netdev_priv(ndev
));
275 #ifdef CONFIG_SBE_PMCC4_NCOMM
277 c4_ebus_interrupt (int irq
, void *dev_instance
)
279 struct net_device
*ndev
= dev_instance
;
281 return c4_ebus_intr_th_handler(netdev_priv(ndev
));
287 void_open (struct net_device
* ndev
)
289 pr_info("%s: trying to open master device !\n", ndev
->name
);
294 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
295 #if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
297 /** Linux 2.4.18-19 **/
299 chan_open (hdlc_device
* hdlc
)
303 if ((ret
= c4_chan_up (DEV_TO_PRIV (hdlc
)->ci
, DEV_TO_PRIV (hdlc
)->channum
)))
306 netif_start_queue (hdlc_to_dev (hdlc
));
307 return 0; /* no error = success */
312 /** Linux 2.4.20 and higher **/
314 chan_open (struct net_device
* ndev
)
316 hdlc_device
*hdlc
= dev_to_hdlc (ndev
);
319 hdlc
->proto
= IF_PROTO_HDLC
;
320 if ((ret
= hdlc_open (hdlc
)))
322 pr_info("hdlc_open failure, err %d.\n", ret
);
325 if ((ret
= c4_chan_up (DEV_TO_PRIV (hdlc
)->ci
, DEV_TO_PRIV (hdlc
)->channum
)))
328 netif_start_queue (hdlc_to_dev (hdlc
));
329 return 0; /* no error = success */
337 chan_open (struct net_device
* ndev
)
339 hdlc_device
*hdlc
= dev_to_hdlc (ndev
);
340 const struct c4_priv
*priv
= hdlc
->priv
;
343 if ((ret
= hdlc_open (ndev
)))
345 pr_info("hdlc_open failure, err %d.\n", ret
);
348 if ((ret
= c4_chan_up (priv
->ci
, priv
->channum
)))
350 try_module_get (THIS_MODULE
);
351 netif_start_queue (ndev
);
352 return 0; /* no error = success */
357 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
358 #if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
360 /** Linux 2.4.18-19 **/
362 chan_close (hdlc_device
* hdlc
)
364 netif_stop_queue (hdlc_to_dev (hdlc
));
365 musycc_chan_down ((ci_t
*) 0, DEV_TO_PRIV (hdlc
)->channum
);
370 /** Linux 2.4.20 and higher **/
372 chan_close (struct net_device
* ndev
)
374 hdlc_device
*hdlc
= dev_to_hdlc (ndev
);
376 netif_stop_queue (hdlc_to_dev (hdlc
));
377 musycc_chan_down ((ci_t
*) 0, DEV_TO_PRIV (hdlc
)->channum
);
388 chan_close (struct net_device
* ndev
)
390 hdlc_device
*hdlc
= dev_to_hdlc (ndev
);
391 const struct c4_priv
*priv
= hdlc
->priv
;
393 netif_stop_queue (ndev
);
394 musycc_chan_down ((ci_t
*) 0, priv
->channum
);
396 module_put (THIS_MODULE
);
402 #if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
404 /** Linux 2.4.18-19 **/
406 chan_ioctl (hdlc_device
* hdlc
, struct ifreq
* ifr
, int cmd
)
408 if (cmd
== HDLCSCLOCK
)
410 ifr
->ifr_ifru
.ifru_ivalue
= LINE_DEFAULT
;
418 #if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
420 chan_dev_ioctl (struct net_device
* hdlc
, struct ifreq
* ifr
, int cmd
)
422 if (cmd
== HDLCSCLOCK
)
424 ifr
->ifr_ifru
.ifru_ivalue
= LINE_DEFAULT
;
431 chan_dev_ioctl (struct net_device
* dev
, struct ifreq
* ifr
, int cmd
)
433 return hdlc_ioctl (dev
, ifr
, cmd
);
438 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
439 chan_attach_noop (hdlc_device
* hdlc
, unsigned short foo_1
, unsigned short foo_2
)
441 chan_attach_noop (struct net_device
* ndev
, unsigned short foo_1
, unsigned short foo_2
)
444 return 0; /* our driver has nothing to do here, show's
450 STATIC
struct net_device_stats
*
451 chan_get_stats (struct net_device
* ndev
)
454 struct net_device_stats
*nstats
;
455 struct sbecom_chan_stats
*stats
;
458 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
459 channum
= DEV_TO_PRIV (ndev
)->channum
;
462 struct c4_priv
*priv
;
464 priv
= (struct c4_priv
*) dev_to_hdlc (ndev
)->priv
;
465 channum
= priv
->channum
;
469 ch
= c4_find_chan (channum
);
473 nstats
= &ndev
->stats
;
476 memset (nstats
, 0, sizeof (struct net_device_stats
));
477 nstats
->rx_packets
= stats
->rx_packets
;
478 nstats
->tx_packets
= stats
->tx_packets
;
479 nstats
->rx_bytes
= stats
->rx_bytes
;
480 nstats
->tx_bytes
= stats
->tx_bytes
;
481 nstats
->rx_errors
= stats
->rx_length_errors
+
482 stats
->rx_over_errors
+
483 stats
->rx_crc_errors
+
484 stats
->rx_frame_errors
+
485 stats
->rx_fifo_errors
+
486 stats
->rx_missed_errors
;
487 nstats
->tx_errors
= stats
->tx_dropped
+
488 stats
->tx_aborted_errors
+
489 stats
->tx_fifo_errors
;
490 nstats
->rx_dropped
= stats
->rx_dropped
;
491 nstats
->tx_dropped
= stats
->tx_dropped
;
493 nstats
->rx_length_errors
= stats
->rx_length_errors
;
494 nstats
->rx_over_errors
= stats
->rx_over_errors
;
495 nstats
->rx_crc_errors
= stats
->rx_crc_errors
;
496 nstats
->rx_frame_errors
= stats
->rx_frame_errors
;
497 nstats
->rx_fifo_errors
= stats
->rx_fifo_errors
;
498 nstats
->rx_missed_errors
= stats
->rx_missed_errors
;
500 nstats
->tx_aborted_errors
= stats
->tx_aborted_errors
;
501 nstats
->tx_fifo_errors
= stats
->tx_fifo_errors
;
508 get_ci_by_dev (struct net_device
* ndev
)
510 return (ci_t
*)(netdev_priv(ndev
));
514 #if !defined(GENERIC_HDLC_VERSION) || (GENERIC_HDLC_VERSION < 4)
516 c4_linux_xmit (hdlc_device
* hdlc
, struct sk_buff
* skb
)
520 rval
= musycc_start_xmit (DEV_TO_PRIV (hdlc
)->ci
, DEV_TO_PRIV (hdlc
)->channum
, skb
);
525 c4_linux_xmit (struct sk_buff
* skb
, struct net_device
* ndev
)
527 const struct c4_priv
*priv
;
530 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
531 priv
= DEV_TO_PRIV (ndev
);
533 hdlc_device
*hdlc
= dev_to_hdlc (ndev
);
538 rval
= musycc_start_xmit (priv
->ci
, priv
->channum
, skb
);
541 #endif /* GENERIC_HDLC_VERSION */
543 static const struct net_device_ops chan_ops
= {
544 .ndo_open
= chan_open
,
545 .ndo_stop
= chan_close
,
546 .ndo_start_xmit
= c4_linux_xmit
,
547 .ndo_do_ioctl
= chan_dev_ioctl
,
548 .ndo_get_stats
= chan_get_stats
,
551 STATIC
struct net_device
*
552 create_chan (struct net_device
* ndev
, ci_t
* ci
,
553 struct sbecom_chan_param
* cp
)
556 struct net_device
*dev
;
560 if (c4_find_chan (cp
->channum
))
561 return 0; /* channel already exists */
564 struct c4_priv
*priv
;
566 /* allocate then fill in private data structure */
567 priv
= OS_kmalloc (sizeof (struct c4_priv
));
570 pr_warning("%s: no memory for net_device !\n", ci
->devname
);
573 dev
= alloc_hdlcdev (priv
);
576 pr_warning("%s: no memory for hdlc_device !\n", ci
->devname
);
581 priv
->channum
= cp
->channum
;
584 hdlc
= dev_to_hdlc (dev
);
586 dev
->base_addr
= 0; /* not I/O mapped */
587 dev
->irq
= ndev
->irq
;
588 dev
->type
= ARPHRD_RAWHDLC
;
589 *dev
->name
= 0; /* default ifconfig name = "hdlc" */
591 hi
= (hdw_info_t
*) ci
->hdw_info
;
592 if (hi
->mfg_info_sts
== EEPROM_OK
)
596 case PROM_FORMAT_TYPE1
:
597 memcpy (dev
->dev_addr
, (FLD_TYPE1
*) (hi
->mfg_info
.pft1
.Serial
), 6);
599 case PROM_FORMAT_TYPE2
:
600 memcpy (dev
->dev_addr
, (FLD_TYPE2
*) (hi
->mfg_info
.pft2
.Serial
), 6);
603 memset (dev
->dev_addr
, 0, 6);
608 memset (dev
->dev_addr
, 0, 6);
611 hdlc
->xmit
= c4_linux_xmit
;
613 dev
->netdev_ops
= &chan_ops
;
615 * The native hdlc stack calls this 'attach' routine during
616 * hdlc_raw_ioctl(), passing parameters for line encoding and parity.
617 * Since hdlc_raw_ioctl() stack does not interrogate whether an 'attach'
618 * routine is actually registered or not, we supply a dummy routine which
619 * does nothing (since encoding and parity are setup for our driver via a
620 * special configuration application).
623 hdlc
->attach
= chan_attach_noop
;
625 rtnl_unlock (); /* needed due to Ioctl calling sequence */
626 ret
= register_hdlc_device (dev
);
627 /* NOTE: <stats> setting must occur AFTER registration in order to "take" */
628 dev
->tx_queue_len
= MAX_DEFAULT_IFQLEN
;
630 rtnl_lock (); /* needed due to Ioctl calling sequence */
633 if (log_level
>= LOG_WARN
)
634 pr_info("%s: create_chan[%d] registration error = %d.\n",
635 ci
->devname
, cp
->channum
, ret
);
636 free_netdev (dev
); /* cleanup */
637 return 0; /* failed to register */
643 /* the idea here is to get port information and pass it back (using pointer) */
645 do_get_port (struct net_device
* ndev
, void *data
)
648 ci_t
*ci
; /* ci stands for card information */
649 struct sbecom_port_param pp
;/* copy data to kernel land */
651 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
653 if (pp
.portnum
>= MUSYCC_NPORTS
)
655 ci
= get_ci_by_dev (ndev
);
657 return -EINVAL
; /* get card info */
659 ret
= mkret (c4_get_port (ci
, pp
.portnum
));
662 if (copy_to_user (data
, &ci
->port
[pp
.portnum
].p
,
663 sizeof (struct sbecom_port_param
)))
668 /* this function copys the user data and then calls the real action function */
670 do_set_port (struct net_device
* ndev
, void *data
)
672 ci_t
*ci
; /* ci stands for card information */
673 struct sbecom_port_param pp
;/* copy data to kernel land */
675 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
677 if (pp
.portnum
>= MUSYCC_NPORTS
)
679 ci
= get_ci_by_dev (ndev
);
681 return -EINVAL
; /* get card info */
683 if (pp
.portnum
>= ci
->max_port
) /* sanity check */
686 memcpy (&ci
->port
[pp
.portnum
].p
, &pp
, sizeof (struct sbecom_port_param
));
687 return mkret (c4_set_port (ci
, pp
.portnum
));
690 /* work the port loopback mode as per directed */
692 do_port_loop (struct net_device
* ndev
, void *data
)
694 struct sbecom_port_param pp
;
697 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
699 ci
= get_ci_by_dev (ndev
);
702 return mkret (c4_loop_port (ci
, pp
.portnum
, pp
.port_mode
));
705 /* set the specified register with the given value / or just read it */
707 do_framer_rw (struct net_device
* ndev
, void *data
)
709 struct sbecom_port_param pp
;
713 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
715 ci
= get_ci_by_dev (ndev
);
718 ret
= mkret (c4_frame_rw (ci
, &pp
));
721 if (copy_to_user (data
, &pp
, sizeof (struct sbecom_port_param
)))
726 /* set the specified register with the given value / or just read it */
728 do_pld_rw (struct net_device
* ndev
, void *data
)
730 struct sbecom_port_param pp
;
734 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
736 ci
= get_ci_by_dev (ndev
);
739 ret
= mkret (c4_pld_rw (ci
, &pp
));
742 if (copy_to_user (data
, &pp
, sizeof (struct sbecom_port_param
)))
747 /* set the specified register with the given value / or just read it */
749 do_musycc_rw (struct net_device
* ndev
, void *data
)
751 struct c4_musycc_param mp
;
755 if (copy_from_user (&mp
, data
, sizeof (struct c4_musycc_param
)))
757 ci
= get_ci_by_dev (ndev
);
760 ret
= mkret (c4_musycc_rw (ci
, &mp
));
763 if (copy_to_user (data
, &mp
, sizeof (struct c4_musycc_param
)))
769 do_get_chan (struct net_device
* ndev
, void *data
)
771 struct sbecom_chan_param cp
;
774 if (copy_from_user (&cp
, data
,
775 sizeof (struct sbecom_chan_param
)))
778 if ((ret
= mkret (c4_get_chan (cp
.channum
, &cp
))))
781 if (copy_to_user (data
, &cp
, sizeof (struct sbecom_chan_param
)))
787 do_set_chan (struct net_device
* ndev
, void *data
)
789 struct sbecom_chan_param cp
;
793 if (copy_from_user (&cp
, data
, sizeof (struct sbecom_chan_param
)))
795 ci
= get_ci_by_dev (ndev
);
798 switch (ret
= mkret (c4_set_chan (cp
.channum
, &cp
)))
808 do_create_chan (struct net_device
* ndev
, void *data
)
811 struct net_device
*dev
;
812 struct sbecom_chan_param cp
;
815 if (copy_from_user (&cp
, data
, sizeof (struct sbecom_chan_param
)))
817 ci
= get_ci_by_dev (ndev
);
820 dev
= create_chan (ndev
, ci
, &cp
);
823 ret
= mkret (c4_new_chan (ci
, cp
.port
, cp
.channum
, dev
));
826 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
827 rtnl_unlock (); /* needed due to Ioctl calling sequence */
828 V7 (unregister_hdlc_device
) (dev_to_hdlc (dev
));
829 rtnl_lock (); /* needed due to Ioctl calling sequence */
830 OS_kfree (DEV_TO_PRIV (dev
));
833 rtnl_unlock (); /* needed due to Ioctl calling sequence */
834 unregister_hdlc_device (dev
);
835 rtnl_lock (); /* needed due to Ioctl calling sequence */
843 do_get_chan_stats (struct net_device
* ndev
, void *data
)
845 struct c4_chan_stats_wrap ccs
;
848 if (copy_from_user (&ccs
, data
,
849 sizeof (struct c4_chan_stats_wrap
)))
851 switch (ret
= mkret (c4_get_chan_stats (ccs
.channum
, &ccs
.stats
)))
858 if (copy_to_user (data
, &ccs
,
859 sizeof (struct c4_chan_stats_wrap
)))
864 do_set_loglevel (struct net_device
* ndev
, void *data
)
866 unsigned int log_level
;
868 if (copy_from_user (&log_level
, data
, sizeof (int)))
870 sbecom_set_loglevel (log_level
);
875 do_deluser (struct net_device
* ndev
, int lockit
)
877 if (ndev
->flags
& IFF_UP
)
883 const struct c4_priv
*priv
;
886 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
887 priv
= DEV_TO_PRIV (ndev
);
889 priv
= (struct c4_priv
*) dev_to_hdlc (ndev
)->priv
;
892 channum
= priv
->channum
;
894 ch
= c4_find_chan (channum
);
897 ch
->user
= 0; /* will be freed, below */
900 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
902 rtnl_unlock (); /* needed if Ioctl calling sequence */
903 V7 (unregister_hdlc_device
) (dev_to_hdlc (ndev
));
905 rtnl_lock (); /* needed if Ioctl calling sequence */
906 OS_kfree (DEV_TO_PRIV (ndev
));
910 rtnl_unlock (); /* needed if Ioctl calling sequence */
911 unregister_hdlc_device (ndev
);
913 rtnl_lock (); /* needed if Ioctl calling sequence */
920 do_del_chan (struct net_device
* musycc_dev
, void *data
)
922 struct sbecom_chan_param cp
;
923 char buf
[sizeof (CHANNAME
) + 3];
924 struct net_device
*dev
;
927 if (copy_from_user (&cp
, data
,
928 sizeof (struct sbecom_chan_param
)))
930 sprintf (buf
, CHANNAME
"%d", cp
.channum
);
931 if (!(dev
= dev_get_by_name (&init_net
, buf
)))
934 ret
= do_deluser (dev
, 1);
937 return c4_del_chan (cp
.channum
);
939 int c4_reset_board (void *);
942 do_reset (struct net_device
* musycc_dev
, void *data
)
944 const struct c4_priv
*priv
;
947 for (i
= 0; i
< 128; i
++)
949 struct net_device
*ndev
;
950 char buf
[sizeof (CHANNAME
) + 3];
952 sprintf (buf
, CHANNAME
"%d", i
);
953 if (!(ndev
= dev_get_by_name(&init_net
, buf
)))
955 priv
= dev_to_hdlc (ndev
)->priv
;
957 if ((unsigned long) (priv
->ci
) ==
958 (unsigned long) (netdev_priv(musycc_dev
)))
960 ndev
->flags
&= ~IFF_UP
;
962 netif_stop_queue (ndev
);
963 do_deluser (ndev
, 1);
971 do_reset_chan_stats (struct net_device
* musycc_dev
, void *data
)
973 struct sbecom_chan_param cp
;
975 if (copy_from_user (&cp
, data
,
976 sizeof (struct sbecom_chan_param
)))
978 return mkret (c4_del_chan_stats (cp
.channum
));
982 c4_ioctl (struct net_device
* ndev
, struct ifreq
* ifr
, int cmd
)
994 struct sbe_brd_info bip
;
995 struct sbe_drv_info dip
;
996 struct sbe_iid_info iip
;
997 struct sbe_brd_addr bap
;
998 struct sbecom_chan_stats stats
;
999 struct sbecom_chan_param param
;
1000 struct temux_card_stats cards
;
1001 struct sbecom_card_param cardp
;
1002 struct sbecom_framer_param frp
;
1007 if (!capable (CAP_SYS_ADMIN
))
1009 if (cmd
!= SIOCDEVPRIVATE
+ 15)
1011 if (!(ci
= get_ci_by_dev (ndev
)))
1013 if (ci
->state
!= C_RUNNING
)
1015 if (copy_from_user (&iocmd
, ifr
->ifr_data
, sizeof (iocmd
)))
1018 if (copy_from_user (&len
, ifr
->ifr_data
+ sizeof (iocmd
), sizeof (len
)))
1023 pr_info("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd
,
1024 _IOC_DIR (iocmd
), _IOC_TYPE (iocmd
), _IOC_NR (iocmd
),
1027 iolen
= _IOC_SIZE (iocmd
);
1028 data
= ifr
->ifr_data
+ sizeof (iocmd
);
1029 if (copy_from_user (&arg
, data
, iolen
))
1035 case SBE_IOC_PORT_GET
:
1036 //pr_info(">> SBE_IOC_PORT_GET Ioctl...\n");
1037 ret
= do_get_port (ndev
, data
);
1039 case SBE_IOC_PORT_SET
:
1040 //pr_info(">> SBE_IOC_PORT_SET Ioctl...\n");
1041 ret
= do_set_port (ndev
, data
);
1043 case SBE_IOC_CHAN_GET
:
1044 //pr_info(">> SBE_IOC_CHAN_GET Ioctl...\n");
1045 ret
= do_get_chan (ndev
, data
);
1047 case SBE_IOC_CHAN_SET
:
1048 //pr_info(">> SBE_IOC_CHAN_SET Ioctl...\n");
1049 ret
= do_set_chan (ndev
, data
);
1052 //pr_info(">> C4_DEL_CHAN Ioctl...\n");
1053 ret
= do_del_chan (ndev
, data
);
1055 case SBE_IOC_CHAN_NEW
:
1056 ret
= do_create_chan (ndev
, data
);
1058 case SBE_IOC_CHAN_GET_STAT
:
1059 ret
= do_get_chan_stats (ndev
, data
);
1061 case SBE_IOC_LOGLEVEL
:
1062 ret
= do_set_loglevel (ndev
, data
);
1064 case SBE_IOC_RESET_DEV
:
1065 ret
= do_reset (ndev
, data
);
1067 case SBE_IOC_CHAN_DEL_STAT
:
1068 ret
= do_reset_chan_stats (ndev
, data
);
1071 ret
= do_port_loop (ndev
, data
);
1074 ret
= do_framer_rw (ndev
, data
);
1077 ret
= do_musycc_rw (ndev
, data
);
1080 ret
= do_pld_rw (ndev
, data
);
1082 case SBE_IOC_IID_GET
:
1083 ret
= (iolen
== sizeof (struct sbe_iid_info
)) ? c4_get_iidinfo (ci
, &arg
.u
.iip
) : -EFAULT
;
1084 if (ret
== 0) /* no error, copy data */
1085 if (copy_to_user (data
, &arg
, iolen
))
1089 //pr_info(">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd);
1096 static const struct net_device_ops c4_ops
= {
1097 .ndo_open
= void_open
,
1098 .ndo_start_xmit
= c4_linux_xmit
,
1099 .ndo_do_ioctl
= c4_ioctl
,
1102 static void c4_setup(struct net_device
*dev
)
1104 dev
->type
= ARPHRD_VOID
;
1105 dev
->netdev_ops
= &c4_ops
;
1108 struct net_device
*__init
1109 c4_add_dev (hdw_info_t
* hi
, int brdno
, unsigned long f0
, unsigned long f1
,
1112 struct net_device
*ndev
;
1115 ndev
= alloc_netdev(sizeof(ci_t
), SBE_IFACETMPL
, c4_setup
);
1118 pr_warning("%s: no memory for struct net_device !\n", hi
->devname
);
1119 error_flag
= ENOMEM
;
1122 ci
= (ci_t
*)(netdev_priv(ndev
));
1126 ci
->state
= C_INIT
; /* mark as hardware not available */
1129 ci
->brdno
= ci
->next
? ci
->next
->brdno
+ 1 : 0;
1132 CI
= ci
; /* DEBUG, only board 0 usage */
1134 strcpy (ci
->devname
, hi
->devname
);
1135 ci
->release
= &pmcc4_OSSI_release
[0];
1138 #if defined(SBE_ISR_TASKLET)
1139 tasklet_init (&ci
->ci_musycc_isr_tasklet
,
1140 (void (*) (unsigned long)) musycc_intr_bh_tasklet
,
1141 (unsigned long) ci
);
1143 if (atomic_read (&ci
->ci_musycc_isr_tasklet
.count
) == 0)
1144 tasklet_disable_nosync (&ci
->ci_musycc_isr_tasklet
);
1145 #elif defined(SBE_ISR_IMMEDIATE)
1146 ci
->ci_musycc_isr_tq
.routine
= (void *) (unsigned long) musycc_intr_bh_tasklet
;
1147 ci
->ci_musycc_isr_tq
.data
= ci
;
1151 if (register_netdev (ndev
) ||
1152 (c4_init (ci
, (u_char
*) f0
, (u_char
*) f1
) != SBE_DRVR_SUCCESS
))
1154 OS_kfree (netdev_priv(ndev
));
1156 error_flag
= ENODEV
;
1159 /*************************************************************
1160 * int request_irq(unsigned int irq,
1161 * void (*handler)(int, void *, struct pt_regs *),
1162 * unsigned long flags, const char *dev_name, void *dev_id);
1164 * irq -> The interrupt number that is being requested.
1165 * handler -> Pointer to handling function being installed.
1166 * flags -> A bit mask of options related to interrupt management.
1167 * dev_name -> String used in /proc/interrupts to show owner of interrupt.
1168 * dev_id -> Pointer (for shared interrupt lines) to point to its own
1169 * private data area (to identify which device is interrupting).
1171 * extern void free_irq(unsigned int irq, void *dev_id);
1172 **************************************************************/
1174 if (request_irq (irq0
, &c4_linux_interrupt
,
1175 #if defined(SBE_ISR_TASKLET)
1176 IRQF_DISABLED
| IRQF_SHARED
,
1177 #elif defined(SBE_ISR_IMMEDIATE)
1178 IRQF_DISABLED
| IRQF_SHARED
,
1179 #elif defined(SBE_ISR_INLINE)
1184 pr_warning("%s: MUSYCC could not get irq: %d\n", ndev
->name
, irq0
);
1185 unregister_netdev (ndev
);
1186 OS_kfree (netdev_priv(ndev
));
1191 #ifdef CONFIG_SBE_PMCC4_NCOMM
1192 if (request_irq (irq1
, &c4_ebus_interrupt
, IRQF_SHARED
, ndev
->name
, ndev
))
1194 pr_warning("%s: EBUS could not get irq: %d\n", hi
->devname
, irq1
);
1195 unregister_netdev (ndev
);
1196 free_irq (irq0
, ndev
);
1197 OS_kfree (netdev_priv(ndev
));
1204 /* setup board identification information */
1209 hdw_sn_get (hi
, brdno
); /* also sets PROM format type (promfmt)
1210 * for later usage */
1212 switch (hi
->promfmt
)
1214 case PROM_FORMAT_TYPE1
:
1215 memcpy (ndev
->dev_addr
, (FLD_TYPE1
*) (hi
->mfg_info
.pft1
.Serial
), 6);
1216 memcpy (&tmp
, (FLD_TYPE1
*) (hi
->mfg_info
.pft1
.Id
), 4); /* unaligned data
1218 ci
->brd_id
= cpu_to_be32 (tmp
);
1220 case PROM_FORMAT_TYPE2
:
1221 memcpy (ndev
->dev_addr
, (FLD_TYPE2
*) (hi
->mfg_info
.pft2
.Serial
), 6);
1222 memcpy (&tmp
, (FLD_TYPE2
*) (hi
->mfg_info
.pft2
.Id
), 4); /* unaligned data
1224 ci
->brd_id
= cpu_to_be32 (tmp
);
1228 memset (ndev
->dev_addr
, 0, 6);
1233 sbeid_set_hdwbid (ci
); /* requires bid to be preset */
1235 sbeid_set_bdtype (ci
); /* requires hdw_bid to be preset */
1240 #ifdef CONFIG_PROC_FS
1241 sbecom_proc_brd_init (ci
);
1243 #if defined(SBE_ISR_TASKLET)
1244 tasklet_enable (&ci
->ci_musycc_isr_tasklet
);
1248 if ((error_flag
= c4_init2 (ci
)) != SBE_DRVR_SUCCESS
)
1250 #ifdef CONFIG_PROC_FS
1251 sbecom_proc_brd_cleanup (ci
);
1253 unregister_netdev (ndev
);
1254 free_irq (irq1
, ndev
);
1255 free_irq (irq0
, ndev
);
1256 OS_kfree (netdev_priv(ndev
));
1258 return 0; /* failure, error_flag is set */
1268 pr_warning("%s\n", pmcc4_OSSI_release
);
1269 if ((rtn
= c4hw_attach_all ()))
1270 return -rtn
; /* installation failure - see system log */
1272 /* housekeeping notifications */
1273 if (log_level
!= log_level_default
)
1274 pr_info("NOTE: driver parameter <log_level> changed from default %d to %d.\n",
1275 log_level_default
, log_level
);
1276 if (max_mru
!= max_mru_default
)
1277 pr_info("NOTE: driver parameter <max_mru> changed from default %d to %d.\n",
1278 max_mru_default
, max_mru
);
1279 if (max_mtu
!= max_mtu_default
)
1280 pr_info("NOTE: driver parameter <max_mtu> changed from default %d to %d.\n",
1281 max_mtu_default
, max_mtu
);
1282 if (max_rxdesc_used
!= max_rxdesc_default
)
1284 if (max_rxdesc_used
> 2000)
1285 max_rxdesc_used
= 2000; /* out-of-bounds reset */
1286 pr_info("NOTE: driver parameter <max_rxdesc_used> changed from default %d to %d.\n",
1287 max_rxdesc_default
, max_rxdesc_used
);
1289 if (max_txdesc_used
!= max_txdesc_default
)
1291 if (max_txdesc_used
> 1000)
1292 max_txdesc_used
= 1000; /* out-of-bounds reset */
1293 pr_info("NOTE: driver parameter <max_txdesc_used> changed from default %d to %d.\n",
1294 max_txdesc_default
, max_txdesc_used
);
1296 return 0; /* installation success */
1301 * find any still allocated hdlc registrations and unregister via call to
1310 struct net_device
*ndev
;
1313 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
1315 if (hi
->ndev
) /* a board has been attached */
1317 ci
= (ci_t
*)(netdev_priv(hi
->ndev
));
1318 for (j
= 0; j
< ci
->max_port
; j
++)
1319 for (k
= 0; k
< MUSYCC_NCHANS
; k
++)
1320 if ((ndev
= ci
->port
[j
].chan
[k
]->user
))
1322 do_deluser (ndev
, 0);
1330 c4_mod_remove (void)
1332 cleanup_hdlc (); /* delete any missed channels */
1336 pr_info("SBE - driver removed.\n");
1339 module_init (c4_mod_init
);
1340 module_exit (c4_mod_remove
);
1342 #ifndef SBE_INCLUDE_SYMBOLS
1343 #ifndef CONFIG_SBE_WANC24_NCOMM
1344 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1350 MODULE_AUTHOR ("SBE Technical Services <support@sbei.com>");
1351 MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module");
1352 #ifdef MODULE_LICENSE
1353 MODULE_LICENSE ("GPL");
1356 /*** End-of-File ***/