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/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"
30 #include "pmcc4_ioctls.h"
31 #include "pmcc4_private.h"
34 /*****************************************************************************************
35 * Error out early if we have compiler trouble.
37 * (This section is included from the kernel's init/main.c as a friendly
38 * spiderman recommendation...)
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.
45 #if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
46 #error Sorry, your GCC is too old. It builds incorrect kernels.
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.
53 /*****************************************************************************************/
55 #define CHANNAME "hdlc"
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);
67 #ifdef CONFIG_SBE_PMCC4_NCOMM
68 irqreturn_t
c4_ebus_intr_th_handler (void *);
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 *);
84 extern char pmcc4_OSSI_release
[];
86 extern struct s_hdw_info hdw_info
[];
88 #if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \
89 defined(CONFIG_SBE_HDLC_V7_MODULE) || defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE)
96 #define V7(x) (x ## _v7)
97 extern int hdlc_netif_rx_v7 (hdlc_device
*, struct sk_buff
*);
98 extern int register_hdlc_device_v7 (hdlc_device
*);
99 extern int unregister_hdlc_device_v7 (hdlc_device
*);
105 int error_flag
; /* module load error reporting */
106 int cxt1e1_log_level
= LOG_ERROR
;
107 int log_level_default
= LOG_ERROR
;
108 module_param(cxt1e1_log_level
, int, 0444);
110 int cxt1e1_max_mru
= MUSYCC_MRU
;
111 int max_mru_default
= MUSYCC_MRU
;
112 module_param(cxt1e1_max_mru
, int, 0444);
114 int cxt1e1_max_mtu
= MUSYCC_MTU
;
115 int max_mtu_default
= MUSYCC_MTU
;
116 module_param(cxt1e1_max_mtu
, int, 0444);
118 int max_txdesc_used
= MUSYCC_TXDESC_MIN
;
119 int max_txdesc_default
= MUSYCC_TXDESC_MIN
;
120 module_param(max_txdesc_used
, int, 0444);
122 int max_rxdesc_used
= MUSYCC_RXDESC_MIN
;
123 int max_rxdesc_default
= MUSYCC_RXDESC_MIN
;
124 module_param(max_rxdesc_used
, int, 0444);
126 /****************************************************************************/
127 /****************************************************************************/
128 /****************************************************************************/
131 getuserbychan (int channum
)
135 ch
= c4_find_chan (channum
);
136 return ch
? ch
->user
: NULL
;
141 get_hdlc_name (hdlc_device
*hdlc
)
143 struct c4_priv
*priv
= hdlc
->priv
;
144 struct net_device
*dev
= getuserbychan (priv
->channum
);
159 /***************************************************************************/
160 #include <linux/workqueue.h>
163 * One workqueue (wq) per port (since musycc allows simultaneous group
164 * commands), with individual data for each channel:
166 * mpi_t -> struct workqueue_struct *wq_port; (dynamically allocated using
167 * create_workqueue())
169 * With work structure (work) statically allocated for each channel:
171 * mch_t -> struct work_struct ch_work; (statically allocated using ???)
177 * Called by the start transmit routine when a channel TX_ENABLE is to be
178 * issued. This queues the transmission start request among other channels
179 * within a port's group.
182 c4_wk_chan_restart (mch_t
*ch
)
186 #ifdef RLD_RESTART_DEBUG
187 pr_info(">> %s: queueing Port %d Chan %d, mch_t @ %p\n",
188 __func__
, pi
->portnum
, ch
->channum
, ch
);
191 /* create new entry w/in workqueue for this channel and let'er rip */
193 /** queue_work (struct workqueue_struct *queue,
194 ** struct work_struct *work);
196 queue_work (pi
->wq_port
, &ch
->ch_work
);
200 c4_wk_chan_init (mpi_t
*pi
, mch_t
*ch
)
203 * this will be used to restart a stopped channel
206 /** INIT_WORK (struct work_struct *work,
207 ** void (*function)(void *),
210 INIT_WORK(&ch
->ch_work
, (void *)musycc_wq_chan_restart
);
211 return 0; /* success */
215 c4_wq_port_init (mpi_t
*pi
)
218 char name
[16], *np
; /* NOTE: name of the queue limited by system
219 * to 10 characters */
222 return 0; /* already initialized */
225 memset (name
, 0, 16);
226 sprintf (np
, "%s%d", pi
->up
->devname
, pi
->portnum
); /* IE pmcc4-01) */
228 #ifdef RLD_RESTART_DEBUG
229 pr_info(">> %s: creating workqueue <%s> for Port %d.\n",
230 __func__
, name
, pi
->portnum
); /* RLD DEBUG */
232 if (!(pi
->wq_port
= create_singlethread_workqueue (name
)))
234 return 0; /* success */
238 c4_wq_port_cleanup (mpi_t
*pi
)
241 * PORT POINT: cannot call this if WQ is statically allocated w/in
242 * structure since it calls kfree(wq);
246 destroy_workqueue (pi
->wq_port
); /* this also calls
247 * flush_workqueue() */
252 /***************************************************************************/
255 c4_linux_interrupt (int irq
, void *dev_instance
)
257 struct net_device
*ndev
= dev_instance
;
259 return musycc_intr_th_handler(netdev_priv(ndev
));
263 #ifdef CONFIG_SBE_PMCC4_NCOMM
265 c4_ebus_interrupt (int irq
, void *dev_instance
)
267 struct net_device
*ndev
= dev_instance
;
269 return c4_ebus_intr_th_handler(netdev_priv(ndev
));
275 void_open (struct net_device
*ndev
)
277 pr_info("%s: trying to open master device !\n", ndev
->name
);
283 chan_open (struct net_device
*ndev
)
285 hdlc_device
*hdlc
= dev_to_hdlc (ndev
);
286 const struct c4_priv
*priv
= hdlc
->priv
;
289 if ((ret
= hdlc_open (ndev
)))
291 pr_info("hdlc_open failure, err %d.\n", ret
);
294 if ((ret
= c4_chan_up (priv
->ci
, priv
->channum
)))
296 try_module_get (THIS_MODULE
);
297 netif_start_queue (ndev
);
298 return 0; /* no error = success */
303 chan_close (struct net_device
*ndev
)
305 hdlc_device
*hdlc
= dev_to_hdlc (ndev
);
306 const struct c4_priv
*priv
= hdlc
->priv
;
308 netif_stop_queue (ndev
);
309 musycc_chan_down ((ci_t
*) 0, priv
->channum
);
311 module_put (THIS_MODULE
);
317 chan_dev_ioctl (struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
319 return hdlc_ioctl (dev
, ifr
, cmd
);
324 chan_attach_noop (struct net_device
*ndev
, unsigned short foo_1
, unsigned short foo_2
)
326 return 0; /* our driver has nothing to do here, show's
331 static struct net_device_stats
*
332 chan_get_stats (struct net_device
*ndev
)
335 struct net_device_stats
*nstats
;
336 struct sbecom_chan_stats
*stats
;
340 struct c4_priv
*priv
;
342 priv
= (struct c4_priv
*) dev_to_hdlc (ndev
)->priv
;
343 channum
= priv
->channum
;
346 ch
= c4_find_chan (channum
);
350 nstats
= &ndev
->stats
;
353 memset (nstats
, 0, sizeof (struct net_device_stats
));
354 nstats
->rx_packets
= stats
->rx_packets
;
355 nstats
->tx_packets
= stats
->tx_packets
;
356 nstats
->rx_bytes
= stats
->rx_bytes
;
357 nstats
->tx_bytes
= stats
->tx_bytes
;
358 nstats
->rx_errors
= stats
->rx_length_errors
+
359 stats
->rx_over_errors
+
360 stats
->rx_crc_errors
+
361 stats
->rx_frame_errors
+
362 stats
->rx_fifo_errors
+
363 stats
->rx_missed_errors
;
364 nstats
->tx_errors
= stats
->tx_dropped
+
365 stats
->tx_aborted_errors
+
366 stats
->tx_fifo_errors
;
367 nstats
->rx_dropped
= stats
->rx_dropped
;
368 nstats
->tx_dropped
= stats
->tx_dropped
;
370 nstats
->rx_length_errors
= stats
->rx_length_errors
;
371 nstats
->rx_over_errors
= stats
->rx_over_errors
;
372 nstats
->rx_crc_errors
= stats
->rx_crc_errors
;
373 nstats
->rx_frame_errors
= stats
->rx_frame_errors
;
374 nstats
->rx_fifo_errors
= stats
->rx_fifo_errors
;
375 nstats
->rx_missed_errors
= stats
->rx_missed_errors
;
377 nstats
->tx_aborted_errors
= stats
->tx_aborted_errors
;
378 nstats
->tx_fifo_errors
= stats
->tx_fifo_errors
;
385 get_ci_by_dev (struct net_device
*ndev
)
387 return (ci_t
*)(netdev_priv(ndev
));
392 c4_linux_xmit (struct sk_buff
*skb
, struct net_device
*ndev
)
394 const struct c4_priv
*priv
;
397 hdlc_device
*hdlc
= dev_to_hdlc (ndev
);
401 rval
= musycc_start_xmit (priv
->ci
, priv
->channum
, skb
);
405 static const struct net_device_ops chan_ops
= {
406 .ndo_open
= chan_open
,
407 .ndo_stop
= chan_close
,
408 .ndo_start_xmit
= c4_linux_xmit
,
409 .ndo_do_ioctl
= chan_dev_ioctl
,
410 .ndo_get_stats
= chan_get_stats
,
413 static struct net_device
*
414 create_chan (struct net_device
*ndev
, ci_t
*ci
,
415 struct sbecom_chan_param
*cp
)
418 struct net_device
*dev
;
422 if (c4_find_chan (cp
->channum
))
423 return NULL
; /* channel already exists */
426 struct c4_priv
*priv
;
428 /* allocate then fill in private data structure */
429 priv
= OS_kmalloc (sizeof (struct c4_priv
));
432 pr_warning("%s: no memory for net_device !\n", ci
->devname
);
435 dev
= alloc_hdlcdev (priv
);
438 pr_warning("%s: no memory for hdlc_device !\n", ci
->devname
);
443 priv
->channum
= cp
->channum
;
446 hdlc
= dev_to_hdlc (dev
);
448 dev
->base_addr
= 0; /* not I/O mapped */
449 dev
->irq
= ndev
->irq
;
450 dev
->type
= ARPHRD_RAWHDLC
;
451 *dev
->name
= 0; /* default ifconfig name = "hdlc" */
453 hi
= (hdw_info_t
*) ci
->hdw_info
;
454 if (hi
->mfg_info_sts
== EEPROM_OK
)
458 case PROM_FORMAT_TYPE1
:
459 memcpy (dev
->dev_addr
, (FLD_TYPE1
*) (hi
->mfg_info
.pft1
.Serial
), 6);
461 case PROM_FORMAT_TYPE2
:
462 memcpy (dev
->dev_addr
, (FLD_TYPE2
*) (hi
->mfg_info
.pft2
.Serial
), 6);
465 memset (dev
->dev_addr
, 0, 6);
470 memset (dev
->dev_addr
, 0, 6);
473 hdlc
->xmit
= c4_linux_xmit
;
475 dev
->netdev_ops
= &chan_ops
;
477 * The native hdlc stack calls this 'attach' routine during
478 * hdlc_raw_ioctl(), passing parameters for line encoding and parity.
479 * Since hdlc_raw_ioctl() stack does not interrogate whether an 'attach'
480 * routine is actually registered or not, we supply a dummy routine which
481 * does nothing (since encoding and parity are setup for our driver via a
482 * special configuration application).
485 hdlc
->attach
= chan_attach_noop
;
487 rtnl_unlock (); /* needed due to Ioctl calling sequence */
488 ret
= register_hdlc_device (dev
);
489 /* NOTE: <stats> setting must occur AFTER registration in order to "take" */
490 dev
->tx_queue_len
= MAX_DEFAULT_IFQLEN
;
492 rtnl_lock (); /* needed due to Ioctl calling sequence */
495 if (cxt1e1_log_level
>= LOG_WARN
)
496 pr_info("%s: create_chan[%d] registration error = %d.\n",
497 ci
->devname
, cp
->channum
, ret
);
498 free_netdev (dev
); /* cleanup */
499 return NULL
; /* failed to register */
505 /* the idea here is to get port information and pass it back (using pointer) */
507 do_get_port (struct net_device
*ndev
, void *data
)
510 ci_t
*ci
; /* ci stands for card information */
511 struct sbecom_port_param pp
;/* copy data to kernel land */
513 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
515 if (pp
.portnum
>= MUSYCC_NPORTS
)
517 ci
= get_ci_by_dev (ndev
);
519 return -EINVAL
; /* get card info */
521 ret
= mkret (c4_get_port (ci
, pp
.portnum
));
524 if (copy_to_user (data
, &ci
->port
[pp
.portnum
].p
,
525 sizeof (struct sbecom_port_param
)))
530 /* this function copys the user data and then calls the real action function */
532 do_set_port (struct net_device
*ndev
, void *data
)
534 ci_t
*ci
; /* ci stands for card information */
535 struct sbecom_port_param pp
;/* copy data to kernel land */
537 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
539 if (pp
.portnum
>= MUSYCC_NPORTS
)
541 ci
= get_ci_by_dev (ndev
);
543 return -EINVAL
; /* get card info */
545 if (pp
.portnum
>= ci
->max_port
) /* sanity check */
548 memcpy (&ci
->port
[pp
.portnum
].p
, &pp
, sizeof (struct sbecom_port_param
));
549 return mkret (c4_set_port (ci
, pp
.portnum
));
552 /* work the port loopback mode as per directed */
554 do_port_loop (struct net_device
*ndev
, void *data
)
556 struct sbecom_port_param pp
;
559 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
561 ci
= get_ci_by_dev (ndev
);
564 return mkret (c4_loop_port (ci
, pp
.portnum
, pp
.port_mode
));
567 /* set the specified register with the given value / or just read it */
569 do_framer_rw (struct net_device
*ndev
, void *data
)
571 struct sbecom_port_param pp
;
575 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
577 ci
= get_ci_by_dev (ndev
);
580 ret
= mkret (c4_frame_rw (ci
, &pp
));
583 if (copy_to_user (data
, &pp
, sizeof (struct sbecom_port_param
)))
588 /* set the specified register with the given value / or just read it */
590 do_pld_rw (struct net_device
*ndev
, void *data
)
592 struct sbecom_port_param pp
;
596 if (copy_from_user (&pp
, data
, sizeof (struct sbecom_port_param
)))
598 ci
= get_ci_by_dev (ndev
);
601 ret
= mkret (c4_pld_rw (ci
, &pp
));
604 if (copy_to_user (data
, &pp
, sizeof (struct sbecom_port_param
)))
609 /* set the specified register with the given value / or just read it */
611 do_musycc_rw (struct net_device
*ndev
, void *data
)
613 struct c4_musycc_param mp
;
617 if (copy_from_user (&mp
, data
, sizeof (struct c4_musycc_param
)))
619 ci
= get_ci_by_dev (ndev
);
622 ret
= mkret (c4_musycc_rw (ci
, &mp
));
625 if (copy_to_user (data
, &mp
, sizeof (struct c4_musycc_param
)))
631 do_get_chan (struct net_device
*ndev
, void *data
)
633 struct sbecom_chan_param cp
;
636 if (copy_from_user (&cp
, data
,
637 sizeof (struct sbecom_chan_param
)))
640 if ((ret
= mkret (c4_get_chan (cp
.channum
, &cp
))))
643 if (copy_to_user (data
, &cp
, sizeof (struct sbecom_chan_param
)))
649 do_set_chan (struct net_device
*ndev
, void *data
)
651 struct sbecom_chan_param cp
;
655 if (copy_from_user (&cp
, data
, sizeof (struct sbecom_chan_param
)))
657 ci
= get_ci_by_dev (ndev
);
660 switch (ret
= mkret (c4_set_chan (cp
.channum
, &cp
)))
670 do_create_chan (struct net_device
*ndev
, void *data
)
673 struct net_device
*dev
;
674 struct sbecom_chan_param cp
;
677 if (copy_from_user (&cp
, data
, sizeof (struct sbecom_chan_param
)))
679 ci
= get_ci_by_dev (ndev
);
682 dev
= create_chan (ndev
, ci
, &cp
);
685 ret
= mkret (c4_new_chan (ci
, cp
.port
, cp
.channum
, dev
));
688 rtnl_unlock (); /* needed due to Ioctl calling sequence */
689 unregister_hdlc_device (dev
);
690 rtnl_lock (); /* needed due to Ioctl calling sequence */
697 do_get_chan_stats (struct net_device
*ndev
, void *data
)
699 struct c4_chan_stats_wrap ccs
;
702 if (copy_from_user (&ccs
, data
,
703 sizeof (struct c4_chan_stats_wrap
)))
705 switch (ret
= mkret (c4_get_chan_stats (ccs
.channum
, &ccs
.stats
)))
712 if (copy_to_user (data
, &ccs
,
713 sizeof (struct c4_chan_stats_wrap
)))
718 do_set_loglevel (struct net_device
*ndev
, void *data
)
720 unsigned int cxt1e1_log_level
;
722 if (copy_from_user (&cxt1e1_log_level
, data
, sizeof (int)))
724 sbecom_set_loglevel (cxt1e1_log_level
);
729 do_deluser (struct net_device
*ndev
, int lockit
)
731 if (ndev
->flags
& IFF_UP
)
737 const struct c4_priv
*priv
;
740 priv
= (struct c4_priv
*) dev_to_hdlc (ndev
)->priv
;
742 channum
= priv
->channum
;
744 ch
= c4_find_chan (channum
);
747 ch
->user
= NULL
; /* will be freed, below */
751 rtnl_unlock (); /* needed if Ioctl calling sequence */
752 unregister_hdlc_device (ndev
);
754 rtnl_lock (); /* needed if Ioctl calling sequence */
760 do_del_chan (struct net_device
*musycc_dev
, void *data
)
762 struct sbecom_chan_param cp
;
763 char buf
[sizeof (CHANNAME
) + 3];
764 struct net_device
*dev
;
767 if (copy_from_user (&cp
, data
,
768 sizeof (struct sbecom_chan_param
)))
770 if (cp
.channum
> 999)
772 snprintf (buf
, sizeof(buf
), CHANNAME
"%d", cp
.channum
);
773 dev
= __dev_get_by_name(&init_net
, buf
);
776 ret
= do_deluser (dev
, 1);
779 return c4_del_chan (cp
.channum
);
781 int c4_reset_board (void *);
784 do_reset (struct net_device
*musycc_dev
, void *data
)
786 const struct c4_priv
*priv
;
789 for (i
= 0; i
< 128; i
++)
791 struct net_device
*ndev
;
792 char buf
[sizeof (CHANNAME
) + 3];
794 sprintf (buf
, CHANNAME
"%d", i
);
795 ndev
= __dev_get_by_name(&init_net
, buf
);
798 priv
= dev_to_hdlc (ndev
)->priv
;
800 if ((unsigned long) (priv
->ci
) ==
801 (unsigned long) (netdev_priv(musycc_dev
)))
803 ndev
->flags
&= ~IFF_UP
;
804 netif_stop_queue (ndev
);
805 do_deluser (ndev
, 1);
812 do_reset_chan_stats (struct net_device
*musycc_dev
, void *data
)
814 struct sbecom_chan_param cp
;
816 if (copy_from_user (&cp
, data
,
817 sizeof (struct sbecom_chan_param
)))
819 return mkret (c4_del_chan_stats (cp
.channum
));
823 c4_ioctl (struct net_device
*ndev
, struct ifreq
*ifr
, int cmd
)
835 struct sbe_brd_info bip
;
836 struct sbe_drv_info dip
;
837 struct sbe_iid_info iip
;
838 struct sbe_brd_addr bap
;
839 struct sbecom_chan_stats stats
;
840 struct sbecom_chan_param param
;
841 struct temux_card_stats cards
;
842 struct sbecom_card_param cardp
;
843 struct sbecom_framer_param frp
;
848 if (!capable (CAP_SYS_ADMIN
))
850 if (cmd
!= SIOCDEVPRIVATE
+ 15)
852 if (!(ci
= get_ci_by_dev (ndev
)))
854 if (ci
->state
!= C_RUNNING
)
856 if (copy_from_user (&iocmd
, ifr
->ifr_data
, sizeof (iocmd
)))
859 if (copy_from_user (&len
, ifr
->ifr_data
+ sizeof (iocmd
), sizeof (len
)))
864 pr_info("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd
,
865 _IOC_DIR (iocmd
), _IOC_TYPE (iocmd
), _IOC_NR (iocmd
),
868 iolen
= _IOC_SIZE (iocmd
);
869 data
= ifr
->ifr_data
+ sizeof (iocmd
);
870 if (copy_from_user (&arg
, data
, iolen
))
876 case SBE_IOC_PORT_GET
:
877 //pr_info(">> SBE_IOC_PORT_GET Ioctl...\n");
878 ret
= do_get_port (ndev
, data
);
880 case SBE_IOC_PORT_SET
:
881 //pr_info(">> SBE_IOC_PORT_SET Ioctl...\n");
882 ret
= do_set_port (ndev
, data
);
884 case SBE_IOC_CHAN_GET
:
885 //pr_info(">> SBE_IOC_CHAN_GET Ioctl...\n");
886 ret
= do_get_chan (ndev
, data
);
888 case SBE_IOC_CHAN_SET
:
889 //pr_info(">> SBE_IOC_CHAN_SET Ioctl...\n");
890 ret
= do_set_chan (ndev
, data
);
893 //pr_info(">> C4_DEL_CHAN Ioctl...\n");
894 ret
= do_del_chan (ndev
, data
);
896 case SBE_IOC_CHAN_NEW
:
897 ret
= do_create_chan (ndev
, data
);
899 case SBE_IOC_CHAN_GET_STAT
:
900 ret
= do_get_chan_stats (ndev
, data
);
902 case SBE_IOC_LOGLEVEL
:
903 ret
= do_set_loglevel (ndev
, data
);
905 case SBE_IOC_RESET_DEV
:
906 ret
= do_reset (ndev
, data
);
908 case SBE_IOC_CHAN_DEL_STAT
:
909 ret
= do_reset_chan_stats (ndev
, data
);
912 ret
= do_port_loop (ndev
, data
);
915 ret
= do_framer_rw (ndev
, data
);
918 ret
= do_musycc_rw (ndev
, data
);
921 ret
= do_pld_rw (ndev
, data
);
923 case SBE_IOC_IID_GET
:
924 ret
= (iolen
== sizeof (struct sbe_iid_info
)) ? c4_get_iidinfo (ci
, &arg
.u
.iip
) : -EFAULT
;
925 if (ret
== 0) /* no error, copy data */
926 if (copy_to_user (data
, &arg
, iolen
))
930 //pr_info(">> c4_ioctl: EINVAL - unknown iocmd <%x>\n", iocmd);
937 static const struct net_device_ops c4_ops
= {
938 .ndo_open
= void_open
,
939 .ndo_start_xmit
= c4_linux_xmit
,
940 .ndo_do_ioctl
= c4_ioctl
,
943 static void c4_setup(struct net_device
*dev
)
945 dev
->type
= ARPHRD_VOID
;
946 dev
->netdev_ops
= &c4_ops
;
949 struct net_device
*__init
950 c4_add_dev (hdw_info_t
*hi
, int brdno
, unsigned long f0
, unsigned long f1
,
953 struct net_device
*ndev
;
956 ndev
= alloc_netdev(sizeof(ci_t
), SBE_IFACETMPL
, c4_setup
);
959 pr_warning("%s: no memory for struct net_device !\n", hi
->devname
);
963 ci
= (ci_t
*)(netdev_priv(ndev
));
967 ci
->state
= C_INIT
; /* mark as hardware not available */
970 ci
->brdno
= ci
->next
? ci
->next
->brdno
+ 1 : 0;
973 CI
= ci
; /* DEBUG, only board 0 usage */
975 strcpy (ci
->devname
, hi
->devname
);
976 ci
->release
= &pmcc4_OSSI_release
[0];
979 #if defined(SBE_ISR_TASKLET)
980 tasklet_init (&ci
->ci_musycc_isr_tasklet
,
981 (void (*) (unsigned long)) musycc_intr_bh_tasklet
,
984 if (atomic_read (&ci
->ci_musycc_isr_tasklet
.count
) == 0)
985 tasklet_disable_nosync (&ci
->ci_musycc_isr_tasklet
);
986 #elif defined(SBE_ISR_IMMEDIATE)
987 ci
->ci_musycc_isr_tq
.routine
= (void *) (unsigned long) musycc_intr_bh_tasklet
;
988 ci
->ci_musycc_isr_tq
.data
= ci
;
992 if (register_netdev (ndev
) ||
993 (c4_init (ci
, (u_char
*) f0
, (u_char
*) f1
) != SBE_DRVR_SUCCESS
))
995 OS_kfree (netdev_priv(ndev
));
1000 /*************************************************************
1001 * int request_irq(unsigned int irq,
1002 * void (*handler)(int, void *, struct pt_regs *),
1003 * unsigned long flags, const char *dev_name, void *dev_id);
1005 * irq -> The interrupt number that is being requested.
1006 * handler -> Pointer to handling function being installed.
1007 * flags -> A bit mask of options related to interrupt management.
1008 * dev_name -> String used in /proc/interrupts to show owner of interrupt.
1009 * dev_id -> Pointer (for shared interrupt lines) to point to its own
1010 * private data area (to identify which device is interrupting).
1012 * extern void free_irq(unsigned int irq, void *dev_id);
1013 **************************************************************/
1015 if (request_irq (irq0
, &c4_linux_interrupt
,
1019 pr_warning("%s: MUSYCC could not get irq: %d\n", ndev
->name
, irq0
);
1020 unregister_netdev (ndev
);
1021 OS_kfree (netdev_priv(ndev
));
1026 #ifdef CONFIG_SBE_PMCC4_NCOMM
1027 if (request_irq (irq1
, &c4_ebus_interrupt
, IRQF_SHARED
, ndev
->name
, ndev
))
1029 pr_warning("%s: EBUS could not get irq: %d\n", hi
->devname
, irq1
);
1030 unregister_netdev (ndev
);
1031 free_irq (irq0
, ndev
);
1032 OS_kfree (netdev_priv(ndev
));
1039 /* setup board identification information */
1044 hdw_sn_get (hi
, brdno
); /* also sets PROM format type (promfmt)
1045 * for later usage */
1047 switch (hi
->promfmt
)
1049 case PROM_FORMAT_TYPE1
:
1050 memcpy (ndev
->dev_addr
, (FLD_TYPE1
*) (hi
->mfg_info
.pft1
.Serial
), 6);
1051 memcpy (&tmp
, (FLD_TYPE1
*) (hi
->mfg_info
.pft1
.Id
), 4); /* unaligned data
1053 ci
->brd_id
= cpu_to_be32 (tmp
);
1055 case PROM_FORMAT_TYPE2
:
1056 memcpy (ndev
->dev_addr
, (FLD_TYPE2
*) (hi
->mfg_info
.pft2
.Serial
), 6);
1057 memcpy (&tmp
, (FLD_TYPE2
*) (hi
->mfg_info
.pft2
.Id
), 4); /* unaligned data
1059 ci
->brd_id
= cpu_to_be32 (tmp
);
1063 memset (ndev
->dev_addr
, 0, 6);
1068 sbeid_set_hdwbid (ci
); /* requires bid to be preset */
1070 sbeid_set_bdtype (ci
); /* requires hdw_bid to be preset */
1075 #ifdef CONFIG_PROC_FS
1076 sbecom_proc_brd_init (ci
);
1078 #if defined(SBE_ISR_TASKLET)
1079 tasklet_enable (&ci
->ci_musycc_isr_tasklet
);
1083 if ((error_flag
= c4_init2 (ci
)) != SBE_DRVR_SUCCESS
)
1085 #ifdef CONFIG_PROC_FS
1086 sbecom_proc_brd_cleanup (ci
);
1088 unregister_netdev (ndev
);
1089 free_irq (irq1
, ndev
);
1090 free_irq (irq0
, ndev
);
1091 OS_kfree (netdev_priv(ndev
));
1093 return NULL
; /* failure, error_flag is set */
1103 pr_warning("%s\n", pmcc4_OSSI_release
);
1104 if ((rtn
= c4hw_attach_all ()))
1105 return -rtn
; /* installation failure - see system log */
1107 /* housekeeping notifications */
1108 if (cxt1e1_log_level
!= log_level_default
)
1109 pr_info("NOTE: driver parameter <cxt1e1_log_level> changed from default %d to %d.\n",
1110 log_level_default
, cxt1e1_log_level
);
1111 if (cxt1e1_max_mru
!= max_mru_default
)
1112 pr_info("NOTE: driver parameter <cxt1e1_max_mru> changed from default %d to %d.\n",
1113 max_mru_default
, cxt1e1_max_mru
);
1114 if (cxt1e1_max_mtu
!= max_mtu_default
)
1115 pr_info("NOTE: driver parameter <cxt1e1_max_mtu> changed from default %d to %d.\n",
1116 max_mtu_default
, cxt1e1_max_mtu
);
1117 if (max_rxdesc_used
!= max_rxdesc_default
)
1119 if (max_rxdesc_used
> 2000)
1120 max_rxdesc_used
= 2000; /* out-of-bounds reset */
1121 pr_info("NOTE: driver parameter <max_rxdesc_used> changed from default %d to %d.\n",
1122 max_rxdesc_default
, max_rxdesc_used
);
1124 if (max_txdesc_used
!= max_txdesc_default
)
1126 if (max_txdesc_used
> 1000)
1127 max_txdesc_used
= 1000; /* out-of-bounds reset */
1128 pr_info("NOTE: driver parameter <max_txdesc_used> changed from default %d to %d.\n",
1129 max_txdesc_default
, max_txdesc_used
);
1131 return 0; /* installation success */
1136 * find any still allocated hdlc registrations and unregister via call to
1145 struct net_device
*ndev
;
1148 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
1150 if (hi
->ndev
) /* a board has been attached */
1152 ci
= (ci_t
*)(netdev_priv(hi
->ndev
));
1153 for (j
= 0; j
< ci
->max_port
; j
++)
1154 for (k
= 0; k
< MUSYCC_NCHANS
; k
++)
1155 if ((ndev
= ci
->port
[j
].chan
[k
]->user
))
1157 do_deluser (ndev
, 0);
1165 c4_mod_remove (void)
1167 cleanup_hdlc(); /* delete any missed channels */
1171 pr_info("SBE - driver removed.\n");
1174 module_init (c4_mod_init
);
1175 module_exit (c4_mod_remove
);
1177 MODULE_AUTHOR ("SBE Technical Services <support@sbei.com>");
1178 MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module");
1179 #ifdef MODULE_LICENSE
1180 MODULE_LICENSE ("GPL");
1183 /*** End-of-File ***/