1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17#include <linux/types.h>
18#include <linux/netdevice.h>
19#include <linux/module.h>
20#include <linux/hdlc.h>
21#include <linux/if_arp.h>
22#include <linux/init.h>
23#include <asm/uaccess.h>
24#include <linux/rtnetlink.h>
25#include <linux/skbuff.h>
26#include "pmcc4_sysdep.h"
27#include "sbecom_inline_linux.h"
28#include "libsbew.h"
29#include "pmcc4.h"
30#include "pmcc4_ioctls.h"
31#include "pmcc4_private.h"
32#include "sbeproc.h"
33
34
35
36
37
38
39
40
41
42
43
44
45#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
46#error Sorry, your GCC is too old. It builds incorrect kernels.
47#endif
48
49#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0
50#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended.
51#endif
52
53
54
55#define CHANNAME "hdlc"
56
57
58
59status_t c4_chan_work_init (mpi_t *, mch_t *);
60void musycc_wq_chan_restart (void *);
61status_t __init c4_init (ci_t *, u_char *, u_char *);
62status_t __init c4_init2 (ci_t *);
63ci_t *__init c4_new (void *);
64int __init c4hw_attach_all (void);
65void __init hdw_sn_get (hdw_info_t *, int);
66
67#ifdef CONFIG_SBE_PMCC4_NCOMM
68irqreturn_t c4_ebus_intr_th_handler (void *);
69
70#endif
71int c4_frame_rw (ci_t *, struct sbecom_port_param *);
72status_t c4_get_port (ci_t *, int);
73int c4_loop_port (ci_t *, int, u_int8_t);
74int c4_musycc_rw (ci_t *, struct c4_musycc_param *);
75int c4_new_chan (ci_t *, int, int, void *);
76status_t c4_set_port (ci_t *, int);
77int c4_pld_rw (ci_t *, struct sbecom_port_param *);
78void cleanup_devs (void);
79void cleanup_ioremap (void);
80status_t musycc_chan_down (ci_t *, int);
81irqreturn_t musycc_intr_th_handler (void *);
82int musycc_start_xmit (ci_t *, int, void *);
83
84extern char pmcc4_OSSI_release[];
85extern ci_t *CI;
86extern struct s_hdw_info hdw_info[];
87
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)
90#define _v7_hdlc_ 1
91#else
92#define _v7_hdlc_ 0
93#endif
94
95#if _v7_hdlc_
96#define V7(x) (x ## _v7)
97extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *);
98extern int register_hdlc_device_v7 (hdlc_device *);
99extern int unregister_hdlc_device_v7 (hdlc_device *);
100
101#else
102#define V7(x) x
103#endif
104
105int error_flag;
106int cxt1e1_log_level = LOG_ERROR;
107int log_level_default = LOG_ERROR;
108module_param(cxt1e1_log_level, int, 0444);
109
110int cxt1e1_max_mru = MUSYCC_MRU;
111int max_mru_default = MUSYCC_MRU;
112module_param(cxt1e1_max_mru, int, 0444);
113
114int cxt1e1_max_mtu = MUSYCC_MTU;
115int max_mtu_default = MUSYCC_MTU;
116module_param(cxt1e1_max_mtu, int, 0444);
117
118int max_txdesc_used = MUSYCC_TXDESC_MIN;
119int max_txdesc_default = MUSYCC_TXDESC_MIN;
120module_param(max_txdesc_used, int, 0444);
121
122int max_rxdesc_used = MUSYCC_RXDESC_MIN;
123int max_rxdesc_default = MUSYCC_RXDESC_MIN;
124module_param(max_rxdesc_used, int, 0444);
125
126
127
128
129
130void *
131getuserbychan (int channum)
132{
133 mch_t *ch;
134
135 ch = c4_find_chan (channum);
136 return ch ? ch->user : 0;
137}
138
139
140char *
141get_hdlc_name (hdlc_device *hdlc)
142{
143 struct c4_priv *priv = hdlc->priv;
144 struct net_device *dev = getuserbychan (priv->channum);
145
146 return dev->name;
147}
148
149
150static status_t
151mkret (int bsd)
152{
153 if (bsd > 0)
154 return -bsd;
155 else
156 return bsd;
157}
158
159
160#include <linux/workqueue.h>
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181void
182c4_wk_chan_restart (mch_t *ch)
183{
184 mpi_t *pi = ch->up;
185
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);
189#endif
190
191
192
193
194
195
196 queue_work (pi->wq_port, &ch->ch_work);
197}
198
199status_t
200c4_wk_chan_init (mpi_t *pi, mch_t *ch)
201{
202
203
204
205
206
207
208
209
210 INIT_WORK(&ch->ch_work, (void *)musycc_wq_chan_restart);
211 return 0;
212}
213
214status_t
215c4_wq_port_init (mpi_t *pi)
216{
217
218 char name[16], *np;
219
220
221 if (pi->wq_port)
222 return 0;
223
224 np = name;
225 memset (name, 0, 16);
226 sprintf (np, "%s%d", pi->up->devname, pi->portnum);
227
228#ifdef RLD_RESTART_DEBUG
229 pr_info(">> %s: creating workqueue <%s> for Port %d.\n",
230 __func__, name, pi->portnum);
231#endif
232 if (!(pi->wq_port = create_singlethread_workqueue (name)))
233 return ENOMEM;
234 return 0;
235}
236
237void
238c4_wq_port_cleanup (mpi_t *pi)
239{
240
241
242
243
244 if (pi->wq_port)
245 {
246 destroy_workqueue (pi->wq_port);
247
248 pi->wq_port = 0;
249 }
250}
251
252
253
254irqreturn_t
255c4_linux_interrupt (int irq, void *dev_instance)
256{
257 struct net_device *ndev = dev_instance;
258
259 return musycc_intr_th_handler(netdev_priv(ndev));
260}
261
262
263#ifdef CONFIG_SBE_PMCC4_NCOMM
264irqreturn_t
265c4_ebus_interrupt (int irq, void *dev_instance)
266{
267 struct net_device *ndev = dev_instance;
268
269 return c4_ebus_intr_th_handler(netdev_priv(ndev));
270}
271#endif
272
273
274static int
275void_open (struct net_device *ndev)
276{
277 pr_info("%s: trying to open master device !\n", ndev->name);
278 return -1;
279}
280
281
282static int
283chan_open (struct net_device *ndev)
284{
285 hdlc_device *hdlc = dev_to_hdlc (ndev);
286 const struct c4_priv *priv = hdlc->priv;
287 int ret;
288
289 if ((ret = hdlc_open (ndev)))
290 {
291 pr_info("hdlc_open failure, err %d.\n", ret);
292 return ret;
293 }
294 if ((ret = c4_chan_up (priv->ci, priv->channum)))
295 return -ret;
296 try_module_get (THIS_MODULE);
297 netif_start_queue (ndev);
298 return 0;
299}
300
301
302static int
303chan_close (struct net_device *ndev)
304{
305 hdlc_device *hdlc = dev_to_hdlc (ndev);
306 const struct c4_priv *priv = hdlc->priv;
307
308 netif_stop_queue (ndev);
309 musycc_chan_down ((ci_t *) 0, priv->channum);
310 hdlc_close (ndev);
311 module_put (THIS_MODULE);
312 return 0;
313}
314
315
316static int
317chan_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
318{
319 return hdlc_ioctl (dev, ifr, cmd);
320}
321
322
323static int
324chan_attach_noop (struct net_device *ndev, unsigned short foo_1, unsigned short foo_2)
325{
326 return 0;
327
328}
329
330
331static struct net_device_stats *
332chan_get_stats (struct net_device *ndev)
333{
334 mch_t *ch;
335 struct net_device_stats *nstats;
336 struct sbecom_chan_stats *stats;
337 int channum;
338
339 {
340 struct c4_priv *priv;
341
342 priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
343 channum = priv->channum;
344 }
345
346 ch = c4_find_chan (channum);
347 if (ch == NULL)
348 return NULL;
349
350 nstats = &ndev->stats;
351 stats = &ch->s;
352
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;
369
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;
376
377 nstats->tx_aborted_errors = stats->tx_aborted_errors;
378 nstats->tx_fifo_errors = stats->tx_fifo_errors;
379
380 return nstats;
381}
382
383
384static ci_t *
385get_ci_by_dev (struct net_device *ndev)
386{
387 return (ci_t *)(netdev_priv(ndev));
388}
389
390
391static int
392c4_linux_xmit (struct sk_buff *skb, struct net_device *ndev)
393{
394 const struct c4_priv *priv;
395 int rval;
396
397 hdlc_device *hdlc = dev_to_hdlc (ndev);
398
399 priv = hdlc->priv;
400
401 rval = musycc_start_xmit (priv->ci, priv->channum, skb);
402 return rval;
403}
404
405static 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,
411};
412
413static struct net_device *
414create_chan (struct net_device *ndev, ci_t *ci,
415 struct sbecom_chan_param *cp)
416{
417 hdlc_device *hdlc;
418 struct net_device *dev;
419 hdw_info_t *hi;
420 int ret;
421
422 if (c4_find_chan (cp->channum))
423 return 0;
424
425 {
426 struct c4_priv *priv;
427
428
429 priv = OS_kmalloc (sizeof (struct c4_priv));
430 if (!priv)
431 {
432 pr_warning("%s: no memory for net_device !\n", ci->devname);
433 return 0;
434 }
435 dev = alloc_hdlcdev (priv);
436 if (!dev)
437 {
438 pr_warning("%s: no memory for hdlc_device !\n", ci->devname);
439 OS_kfree (priv);
440 return 0;
441 }
442 priv->ci = ci;
443 priv->channum = cp->channum;
444 }
445
446 hdlc = dev_to_hdlc (dev);
447
448 dev->base_addr = 0;
449 dev->irq = ndev->irq;
450 dev->type = ARPHRD_RAWHDLC;
451 *dev->name = 0;
452
453 hi = (hdw_info_t *) ci->hdw_info;
454 if (hi->mfg_info_sts == EEPROM_OK)
455 {
456 switch (hi->promfmt)
457 {
458 case PROM_FORMAT_TYPE1:
459 memcpy (dev->dev_addr, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
460 break;
461 case PROM_FORMAT_TYPE2:
462 memcpy (dev->dev_addr, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
463 break;
464 default:
465 memset (dev->dev_addr, 0, 6);
466 break;
467 }
468 } else
469 {
470 memset (dev->dev_addr, 0, 6);
471 }
472
473 hdlc->xmit = c4_linux_xmit;
474
475 dev->netdev_ops = &chan_ops;
476
477
478
479
480
481
482
483
484
485 hdlc->attach = chan_attach_noop;
486
487 rtnl_unlock ();
488 ret = register_hdlc_device (dev);
489
490 dev->tx_queue_len = MAX_DEFAULT_IFQLEN;
491
492 rtnl_lock ();
493 if (ret)
494 {
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);
499 return 0;
500 }
501 return dev;
502}
503
504
505
506static status_t
507do_get_port (struct net_device *ndev, void *data)
508{
509 int ret;
510 ci_t *ci;
511 struct sbecom_port_param pp;
512
513 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
514 return -EFAULT;
515 if (pp.portnum >= MUSYCC_NPORTS)
516 return -EFAULT;
517 ci = get_ci_by_dev (ndev);
518 if (!ci)
519 return -EINVAL;
520
521 ret = mkret (c4_get_port (ci, pp.portnum));
522 if (ret)
523 return ret;
524 if (copy_to_user (data, &ci->port[pp.portnum].p,
525 sizeof (struct sbecom_port_param)))
526 return -EFAULT;
527 return 0;
528}
529
530
531static status_t
532do_set_port (struct net_device *ndev, void *data)
533{
534 ci_t *ci;
535 struct sbecom_port_param pp;
536
537 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
538 return -EFAULT;
539 if (pp.portnum >= MUSYCC_NPORTS)
540 return -EFAULT;
541 ci = get_ci_by_dev (ndev);
542 if (!ci)
543 return -EINVAL;
544
545 if (pp.portnum >= ci->max_port)
546 return -ENXIO;
547
548 memcpy (&ci->port[pp.portnum].p, &pp, sizeof (struct sbecom_port_param));
549 return mkret (c4_set_port (ci, pp.portnum));
550}
551
552
553static status_t
554do_port_loop (struct net_device *ndev, void *data)
555{
556 struct sbecom_port_param pp;
557 ci_t *ci;
558
559 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
560 return -EFAULT;
561 ci = get_ci_by_dev (ndev);
562 if (!ci)
563 return -EINVAL;
564 return mkret (c4_loop_port (ci, pp.portnum, pp.port_mode));
565}
566
567
568static status_t
569do_framer_rw (struct net_device *ndev, void *data)
570{
571 struct sbecom_port_param pp;
572 ci_t *ci;
573 int ret;
574
575 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
576 return -EFAULT;
577 ci = get_ci_by_dev (ndev);
578 if (!ci)
579 return -EINVAL;
580 ret = mkret (c4_frame_rw (ci, &pp));
581 if (ret)
582 return ret;
583 if (copy_to_user (data, &pp, sizeof (struct sbecom_port_param)))
584 return -EFAULT;
585 return 0;
586}
587
588
589static status_t
590do_pld_rw (struct net_device *ndev, void *data)
591{
592 struct sbecom_port_param pp;
593 ci_t *ci;
594 int ret;
595
596 if (copy_from_user (&pp, data, sizeof (struct sbecom_port_param)))
597 return -EFAULT;
598 ci = get_ci_by_dev (ndev);
599 if (!ci)
600 return -EINVAL;
601 ret = mkret (c4_pld_rw (ci, &pp));
602 if (ret)
603 return ret;
604 if (copy_to_user (data, &pp, sizeof (struct sbecom_port_param)))
605 return -EFAULT;
606 return 0;
607}
608
609
610static status_t
611do_musycc_rw (struct net_device *ndev, void *data)
612{
613 struct c4_musycc_param mp;
614 ci_t *ci;
615 int ret;
616
617 if (copy_from_user (&mp, data, sizeof (struct c4_musycc_param)))
618 return -EFAULT;
619 ci = get_ci_by_dev (ndev);
620 if (!ci)
621 return -EINVAL;
622 ret = mkret (c4_musycc_rw (ci, &mp));
623 if (ret)
624 return ret;
625 if (copy_to_user (data, &mp, sizeof (struct c4_musycc_param)))
626 return -EFAULT;
627 return 0;
628}
629
630static status_t
631do_get_chan (struct net_device *ndev, void *data)
632{
633 struct sbecom_chan_param cp;
634 int ret;
635
636 if (copy_from_user (&cp, data,
637 sizeof (struct sbecom_chan_param)))
638 return -EFAULT;
639
640 if ((ret = mkret (c4_get_chan (cp.channum, &cp))))
641 return ret;
642
643 if (copy_to_user (data, &cp, sizeof (struct sbecom_chan_param)))
644 return -EFAULT;
645 return 0;
646}
647
648static status_t
649do_set_chan (struct net_device *ndev, void *data)
650{
651 struct sbecom_chan_param cp;
652 int ret;
653 ci_t *ci;
654
655 if (copy_from_user (&cp, data, sizeof (struct sbecom_chan_param)))
656 return -EFAULT;
657 ci = get_ci_by_dev (ndev);
658 if (!ci)
659 return -EINVAL;
660 switch (ret = mkret (c4_set_chan (cp.channum, &cp)))
661 {
662 case 0:
663 return 0;
664 default:
665 return ret;
666 }
667}
668
669static status_t
670do_create_chan (struct net_device *ndev, void *data)
671{
672 ci_t *ci;
673 struct net_device *dev;
674 struct sbecom_chan_param cp;
675 int ret;
676
677 if (copy_from_user (&cp, data, sizeof (struct sbecom_chan_param)))
678 return -EFAULT;
679 ci = get_ci_by_dev (ndev);
680 if (!ci)
681 return -EINVAL;
682 dev = create_chan (ndev, ci, &cp);
683 if (!dev)
684 return -EBUSY;
685 ret = mkret (c4_new_chan (ci, cp.port, cp.channum, dev));
686 if (ret)
687 {
688 rtnl_unlock ();
689 unregister_hdlc_device (dev);
690 rtnl_lock ();
691 free_netdev (dev);
692 }
693 return ret;
694}
695
696static status_t
697do_get_chan_stats (struct net_device *ndev, void *data)
698{
699 struct c4_chan_stats_wrap ccs;
700 int ret;
701
702 if (copy_from_user (&ccs, data,
703 sizeof (struct c4_chan_stats_wrap)))
704 return -EFAULT;
705 switch (ret = mkret (c4_get_chan_stats (ccs.channum, &ccs.stats)))
706 {
707 case 0:
708 break;
709 default:
710 return ret;
711 }
712 if (copy_to_user (data, &ccs,
713 sizeof (struct c4_chan_stats_wrap)))
714 return -EFAULT;
715 return 0;
716}
717static status_t
718do_set_loglevel (struct net_device *ndev, void *data)
719{
720 unsigned int cxt1e1_log_level;
721
722 if (copy_from_user (&cxt1e1_log_level, data, sizeof (int)))
723 return -EFAULT;
724 sbecom_set_loglevel (cxt1e1_log_level);
725 return 0;
726}
727
728static status_t
729do_deluser (struct net_device *ndev, int lockit)
730{
731 if (ndev->flags & IFF_UP)
732 return -EBUSY;
733
734 {
735 ci_t *ci;
736 mch_t *ch;
737 const struct c4_priv *priv;
738 int channum;
739
740 priv = (struct c4_priv *) dev_to_hdlc (ndev)->priv;
741 ci = priv->ci;
742 channum = priv->channum;
743
744 ch = c4_find_chan (channum);
745 if (ch == NULL)
746 return -ENOENT;
747 ch->user = 0;
748 }
749
750 if (lockit)
751 rtnl_unlock ();
752 unregister_hdlc_device (ndev);
753 if (lockit)
754 rtnl_lock ();
755 free_netdev (ndev);
756 return 0;
757}
758
759int
760do_del_chan (struct net_device *musycc_dev, void *data)
761{
762 struct sbecom_chan_param cp;
763 char buf[sizeof (CHANNAME) + 3];
764 struct net_device *dev;
765 int ret;
766
767 if (copy_from_user (&cp, data,
768 sizeof (struct sbecom_chan_param)))
769 return -EFAULT;
770 if (cp.channum > 999)
771 return -EINVAL;
772 snprintf (buf, sizeof(buf), CHANNAME "%d", cp.channum);
773 if (!(dev = dev_get_by_name (&init_net, buf)))
774 return -ENOENT;
775 dev_put (dev);
776 ret = do_deluser (dev, 1);
777 if (ret)
778 return ret;
779 return c4_del_chan (cp.channum);
780}
781int c4_reset_board (void *);
782
783int
784do_reset (struct net_device *musycc_dev, void *data)
785{
786 const struct c4_priv *priv;
787 int i;
788
789 for (i = 0; i < 128; i++)
790 {
791 struct net_device *ndev;
792 char buf[sizeof (CHANNAME) + 3];
793
794 sprintf (buf, CHANNAME "%d", i);
795 if (!(ndev = dev_get_by_name(&init_net, buf)))
796 continue;
797 priv = dev_to_hdlc (ndev)->priv;
798
799 if ((unsigned long) (priv->ci) ==
800 (unsigned long) (netdev_priv(musycc_dev)))
801 {
802 ndev->flags &= ~IFF_UP;
803 dev_put (ndev);
804 netif_stop_queue (ndev);
805 do_deluser (ndev, 1);
806 } else
807 dev_put (ndev);
808 }
809 return 0;
810}
811
812int
813do_reset_chan_stats (struct net_device *musycc_dev, void *data)
814{
815 struct sbecom_chan_param cp;
816
817 if (copy_from_user (&cp, data,
818 sizeof (struct sbecom_chan_param)))
819 return -EFAULT;
820 return mkret (c4_del_chan_stats (cp.channum));
821}
822
823static status_t
824c4_ioctl (struct net_device *ndev, struct ifreq *ifr, int cmd)
825{
826 ci_t *ci;
827 void *data;
828 int iocmd, iolen;
829 status_t ret;
830 static struct data
831 {
832 union
833 {
834 u_int8_t c;
835 u_int32_t i;
836 struct sbe_brd_info bip;
837 struct sbe_drv_info dip;
838 struct sbe_iid_info iip;
839 struct sbe_brd_addr bap;
840 struct sbecom_chan_stats stats;
841 struct sbecom_chan_param param;
842 struct temux_card_stats cards;
843 struct sbecom_card_param cardp;
844 struct sbecom_framer_param frp;
845 } u;
846 } arg;
847
848
849 if (!capable (CAP_SYS_ADMIN))
850 return -EPERM;
851 if (cmd != SIOCDEVPRIVATE + 15)
852 return -EINVAL;
853 if (!(ci = get_ci_by_dev (ndev)))
854 return -EINVAL;
855 if (ci->state != C_RUNNING)
856 return -ENODEV;
857 if (copy_from_user (&iocmd, ifr->ifr_data, sizeof (iocmd)))
858 return -EFAULT;
859#if 0
860 if (copy_from_user (&len, ifr->ifr_data + sizeof (iocmd), sizeof (len)))
861 return -EFAULT;
862#endif
863
864#if 0
865 pr_info("c4_ioctl: iocmd %x, dir %x type %x nr %x iolen %d.\n", iocmd,
866 _IOC_DIR (iocmd), _IOC_TYPE (iocmd), _IOC_NR (iocmd),
867 _IOC_SIZE (iocmd));
868#endif
869 iolen = _IOC_SIZE (iocmd);
870 data = ifr->ifr_data + sizeof (iocmd);
871 if (copy_from_user (&arg, data, iolen))
872 return -EFAULT;
873
874 ret = 0;
875 switch (iocmd)
876 {
877 case SBE_IOC_PORT_GET:
878
879 ret = do_get_port (ndev, data);
880 break;
881 case SBE_IOC_PORT_SET:
882
883 ret = do_set_port (ndev, data);
884 break;
885 case SBE_IOC_CHAN_GET:
886
887 ret = do_get_chan (ndev, data);
888 break;
889 case SBE_IOC_CHAN_SET:
890
891 ret = do_set_chan (ndev, data);
892 break;
893 case C4_DEL_CHAN:
894
895 ret = do_del_chan (ndev, data);
896 break;
897 case SBE_IOC_CHAN_NEW:
898 ret = do_create_chan (ndev, data);
899 break;
900 case SBE_IOC_CHAN_GET_STAT:
901 ret = do_get_chan_stats (ndev, data);
902 break;
903 case SBE_IOC_LOGLEVEL:
904 ret = do_set_loglevel (ndev, data);
905 break;
906 case SBE_IOC_RESET_DEV:
907 ret = do_reset (ndev, data);
908 break;
909 case SBE_IOC_CHAN_DEL_STAT:
910 ret = do_reset_chan_stats (ndev, data);
911 break;
912 case C4_LOOP_PORT:
913 ret = do_port_loop (ndev, data);
914 break;
915 case C4_RW_FRMR:
916 ret = do_framer_rw (ndev, data);
917 break;
918 case C4_RW_MSYC:
919 ret = do_musycc_rw (ndev, data);
920 break;
921 case C4_RW_PLD:
922 ret = do_pld_rw (ndev, data);
923 break;
924 case SBE_IOC_IID_GET:
925 ret = (iolen == sizeof (struct sbe_iid_info)) ? c4_get_iidinfo (ci, &arg.u.iip) : -EFAULT;
926 if (ret == 0)
927 if (copy_to_user (data, &arg, iolen))
928 return -EFAULT;
929 break;
930 default:
931
932 ret = -EINVAL;
933 break;
934 }
935 return mkret (ret);
936}
937
938static const struct net_device_ops c4_ops = {
939 .ndo_open = void_open,
940 .ndo_start_xmit = c4_linux_xmit,
941 .ndo_do_ioctl = c4_ioctl,
942};
943
944static void c4_setup(struct net_device *dev)
945{
946 dev->type = ARPHRD_VOID;
947 dev->netdev_ops = &c4_ops;
948}
949
950struct net_device *__init
951c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
952 int irq0, int irq1)
953{
954 struct net_device *ndev;
955 ci_t *ci;
956
957 ndev = alloc_netdev(sizeof(ci_t), SBE_IFACETMPL, c4_setup);
958 if (!ndev)
959 {
960 pr_warning("%s: no memory for struct net_device !\n", hi->devname);
961 error_flag = ENOMEM;
962 return 0;
963 }
964 ci = (ci_t *)(netdev_priv(ndev));
965 ndev->irq = irq0;
966
967 ci->hdw_info = hi;
968 ci->state = C_INIT;
969 ci->next = c4_list;
970 c4_list = ci;
971 ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
972
973 if (CI == 0)
974 CI = ci;
975
976 strcpy (ci->devname, hi->devname);
977 ci->release = &pmcc4_OSSI_release[0];
978
979
980#if defined(SBE_ISR_TASKLET)
981 tasklet_init (&ci->ci_musycc_isr_tasklet,
982 (void (*) (unsigned long)) musycc_intr_bh_tasklet,
983 (unsigned long) ci);
984
985 if (atomic_read (&ci->ci_musycc_isr_tasklet.count) == 0)
986 tasklet_disable_nosync (&ci->ci_musycc_isr_tasklet);
987#elif defined(SBE_ISR_IMMEDIATE)
988 ci->ci_musycc_isr_tq.routine = (void *) (unsigned long) musycc_intr_bh_tasklet;
989 ci->ci_musycc_isr_tq.data = ci;
990#endif
991
992
993 if (register_netdev (ndev) ||
994 (c4_init (ci, (u_char *) f0, (u_char *) f1) != SBE_DRVR_SUCCESS))
995 {
996 OS_kfree (netdev_priv(ndev));
997 OS_kfree (ndev);
998 error_flag = ENODEV;
999 return 0;
1000 }
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 if (request_irq (irq0, &c4_linux_interrupt,
1017 IRQF_SHARED,
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
1041
1042 {
1043 u_int32_t tmp;
1044
1045 hdw_sn_get (hi, brdno);
1046
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);
1053
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);
1059
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#if 1
1069 sbeid_set_hdwbid (ci);
1070#else
1071 sbeid_set_bdtype (ci);
1072#endif
1073
1074 }
1075
1076#ifdef CONFIG_PROC_FS
1077 sbecom_proc_brd_init (ci);
1078#endif
1079#if defined(SBE_ISR_TASKLET)
1080 tasklet_enable (&ci->ci_musycc_isr_tasklet);
1081#endif
1082
1083
1084 if ((error_flag = c4_init2 (ci)) != SBE_DRVR_SUCCESS)
1085 {
1086#ifdef CONFIG_PROC_FS
1087 sbecom_proc_brd_cleanup (ci);
1088#endif
1089 unregister_netdev (ndev);
1090 free_irq (irq1, ndev);
1091 free_irq (irq0, ndev);
1092 OS_kfree (netdev_priv(ndev));
1093 OS_kfree (ndev);
1094 return 0;
1095 }
1096 return ndev;
1097}
1098
1099static int __init
1100c4_mod_init (void)
1101{
1102 int rtn;
1103
1104 pr_warning("%s\n", pmcc4_OSSI_release);
1105 if ((rtn = c4hw_attach_all ()))
1106 return -rtn;
1107
1108
1109 if (cxt1e1_log_level != log_level_default)
1110 pr_info("NOTE: driver parameter <cxt1e1_log_level> changed from default %d to %d.\n",
1111 log_level_default, cxt1e1_log_level);
1112 if (cxt1e1_max_mru != max_mru_default)
1113 pr_info("NOTE: driver parameter <cxt1e1_max_mru> changed from default %d to %d.\n",
1114 max_mru_default, cxt1e1_max_mru);
1115 if (cxt1e1_max_mtu != max_mtu_default)
1116 pr_info("NOTE: driver parameter <cxt1e1_max_mtu> changed from default %d to %d.\n",
1117 max_mtu_default, cxt1e1_max_mtu);
1118 if (max_rxdesc_used != max_rxdesc_default)
1119 {
1120 if (max_rxdesc_used > 2000)
1121 max_rxdesc_used = 2000;
1122 pr_info("NOTE: driver parameter <max_rxdesc_used> changed from default %d to %d.\n",
1123 max_rxdesc_default, max_rxdesc_used);
1124 }
1125 if (max_txdesc_used != max_txdesc_default)
1126 {
1127 if (max_txdesc_used > 1000)
1128 max_txdesc_used = 1000;
1129 pr_info("NOTE: driver parameter <max_txdesc_used> changed from default %d to %d.\n",
1130 max_txdesc_default, max_txdesc_used);
1131 }
1132 return 0;
1133}
1134
1135
1136
1137
1138
1139
1140
1141static void __exit
1142cleanup_hdlc (void)
1143{
1144 hdw_info_t *hi;
1145 ci_t *ci;
1146 struct net_device *ndev;
1147 int i, j, k;
1148
1149 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
1150 {
1151 if (hi->ndev)
1152 {
1153 ci = (ci_t *)(netdev_priv(hi->ndev));
1154 for (j = 0; j < ci->max_port; j++)
1155 for (k = 0; k < MUSYCC_NCHANS; k++)
1156 if ((ndev = ci->port[j].chan[k]->user))
1157 {
1158 do_deluser (ndev, 0);
1159 }
1160 }
1161 }
1162}
1163
1164
1165static void __exit
1166c4_mod_remove (void)
1167{
1168 cleanup_hdlc();
1169 cleanup_devs();
1170 c4_cleanup();
1171 cleanup_ioremap();
1172 pr_info("SBE - driver removed.\n");
1173}
1174
1175module_init (c4_mod_init);
1176module_exit (c4_mod_remove);
1177
1178MODULE_AUTHOR ("SBE Technical Services <support@sbei.com>");
1179MODULE_DESCRIPTION ("wanPCI-CxT1E1 Generic HDLC WAN Driver module");
1180#ifdef MODULE_LICENSE
1181MODULE_LICENSE ("GPL");
1182#endif
1183
1184
1185