linux.c 33 KB

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