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