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