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