sealevel.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Sealevel Systems 4021 driver.
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version
  7.  * 2 of the License, or (at your option) any later version.
  8.  *
  9.  * (c) Copyright 1999, 2001 Alan Cox
  10.  * (c) Copyright 2001 Red Hat Inc.
  11.  *
  12.  */
  13. #include <linux/module.h>
  14. #include <linux/kernel.h>
  15. #include <linux/mm.h>
  16. #include <linux/net.h>
  17. #include <linux/skbuff.h>
  18. #include <linux/netdevice.h>
  19. #include <linux/if_arp.h>
  20. #include <linux/delay.h>
  21. #include <linux/ioport.h>
  22. #include <net/arp.h>
  23. #include <asm/io.h>
  24. #include <asm/dma.h>
  25. #include <asm/byteorder.h>
  26. #include <net/syncppp.h>
  27. #include "z85230.h"
  28. struct slvl_device
  29. {
  30. void *if_ptr; /* General purpose pointer (used by SPPP) */
  31. struct z8530_channel *chan;
  32. struct ppp_device netdev;
  33. int channel;
  34. };
  35. struct slvl_board
  36. {
  37. struct slvl_device dev[2];
  38. struct z8530_dev board;
  39. int iobase;
  40. };
  41. /*
  42.  * Network driver support routines
  43.  */
  44. /*
  45.  * Frame receive. Simple for our card as we do sync ppp and there
  46.  * is no funny garbage involved
  47.  */
  48.  
  49. static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb)
  50. {
  51. /* Drop the CRC - its not a good idea to try and negotiate it ;) */
  52. skb_trim(skb, skb->len-2);
  53. skb->protocol=htons(ETH_P_WAN_PPP);
  54. skb->mac.raw=skb->data;
  55. skb->dev=c->netdevice;
  56. /*
  57.  * Send it to the PPP layer. We dont have time to process
  58.  * it right now.
  59.  */
  60. netif_rx(skb);
  61. c->netdevice->last_rx = jiffies;
  62. }
  63.  
  64. /*
  65.  * We've been placed in the UP state
  66.  */ 
  67.  
  68. static int sealevel_open(struct net_device *d)
  69. {
  70. struct slvl_device *slvl=d->priv;
  71. int err = -1;
  72. int unit = slvl->channel;
  73. /*
  74.  * Link layer up. 
  75.  */
  76. switch(unit)
  77. {
  78. case 0:
  79. err=z8530_sync_dma_open(d, slvl->chan);
  80. break;
  81. case 1:
  82. err=z8530_sync_open(d, slvl->chan);
  83. break;
  84. }
  85. if(err)
  86. return err;
  87. /*
  88.  * Begin PPP
  89.  */
  90. err=sppp_open(d);
  91. if(err)
  92. {
  93. switch(unit)
  94. {
  95. case 0:
  96. z8530_sync_dma_close(d, slvl->chan);
  97. break;
  98. case 1:
  99. z8530_sync_close(d, slvl->chan);
  100. break;
  101. }
  102. return err;
  103. }
  104. slvl->chan->rx_function=sealevel_input;
  105. /*
  106.  * Go go go
  107.  */
  108. netif_start_queue(d);
  109. MOD_INC_USE_COUNT;
  110. return 0;
  111. }
  112. static int sealevel_close(struct net_device *d)
  113. {
  114. struct slvl_device *slvl=d->priv;
  115. int unit = slvl->channel;
  116. /*
  117.  * Discard new frames
  118.  */
  119. slvl->chan->rx_function=z8530_null_rx;
  120. /*
  121.  * PPP off
  122.  */
  123. sppp_close(d);
  124. /*
  125.  * Link layer down
  126.  */
  127. netif_stop_queue(d);
  128. switch(unit)
  129. {
  130. case 0:
  131. z8530_sync_dma_close(d, slvl->chan);
  132. break;
  133. case 1:
  134. z8530_sync_close(d, slvl->chan);
  135. break;
  136. }
  137. MOD_DEC_USE_COUNT;
  138. return 0;
  139. }
  140. static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
  141. {
  142. /* struct slvl_device *slvl=d->priv;
  143.    z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd) */
  144. return sppp_do_ioctl(d, ifr,cmd);
  145. }
  146. static struct net_device_stats *sealevel_get_stats(struct net_device *d)
  147. {
  148. struct slvl_device *slvl=d->priv;
  149. if(slvl)
  150. return z8530_get_stats(slvl->chan);
  151. else
  152. return NULL;
  153. }
  154. /*
  155.  * Passed PPP frames, fire them downwind.
  156.  */
  157.  
  158. static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d)
  159. {
  160. struct slvl_device *slvl=d->priv;
  161. return z8530_queue_xmit(slvl->chan, skb);
  162. }
  163. static int sealevel_neigh_setup(struct neighbour *n)
  164. {
  165. if (n->nud_state == NUD_NONE) {
  166. n->ops = &arp_broken_ops;
  167. n->output = n->ops->output;
  168. }
  169. return 0;
  170. }
  171. static int sealevel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
  172. {
  173. if (p->tbl->family == AF_INET) {
  174. p->neigh_setup = sealevel_neigh_setup;
  175. p->ucast_probes = 0;
  176. p->mcast_probes = 0;
  177. }
  178. return 0;
  179. }
  180. /*
  181.  * Description block for a Comtrol Hostess SV11 card
  182.  */
  183.  
  184. static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, int slow)
  185. {
  186. struct z8530_dev *dev;
  187. struct slvl_device *sv;
  188. struct slvl_board *b;
  189. unsigned long flags;
  190. int u;
  191. /*
  192.  * Get the needed I/O space
  193.  */
  194.  
  195. if(!request_region(iobase, 8, "Sealevel 4021"))
  196. {
  197. printk(KERN_WARNING "sealevel: I/O 0x%X already in use.n", iobase);
  198. return NULL;
  199. }
  200. b=(struct slvl_board *)kmalloc(sizeof(struct slvl_board), GFP_KERNEL);
  201. if(!b)
  202. goto fail3;
  203. memset(b, 0, sizeof(*sv));
  204. b->dev[0].chan = &b->board.chanA;
  205. b->dev[0].if_ptr = &b->dev[0].netdev;
  206. b->dev[0].netdev.dev=(struct net_device *)
  207. kmalloc(sizeof(struct net_device), GFP_KERNEL);
  208. if(!b->dev[0].netdev.dev)
  209. goto fail2;
  210. b->dev[1].chan = &b->board.chanB;
  211. b->dev[1].if_ptr = &b->dev[1].netdev;
  212. b->dev[1].netdev.dev=(struct net_device *)
  213. kmalloc(sizeof(struct net_device), GFP_KERNEL);
  214. if(!b->dev[1].netdev.dev)
  215. goto fail1_0;
  216. dev=&b->board;
  217. /*
  218.  * Stuff in the I/O addressing
  219.  */
  220.  
  221. dev->active = 0;
  222. b->iobase = iobase;
  223. /*
  224.  * Select 8530 delays for the old board
  225.  */
  226.  
  227. if(slow)
  228. iobase |= Z8530_PORT_SLEEP;
  229. dev->chanA.ctrlio=iobase+1;
  230. dev->chanA.dataio=iobase;
  231. dev->chanB.ctrlio=iobase+3;
  232. dev->chanB.dataio=iobase+2;
  233. dev->chanA.irqs=&z8530_nop;
  234. dev->chanB.irqs=&z8530_nop;
  235. /*
  236.  * Assert DTR enable DMA
  237.  */
  238.  
  239. outb(3|(1<<7), b->iobase+4);
  240. /* We want a fast IRQ for this device. Actually we'd like an even faster
  241.    IRQ ;) - This is one driver RtLinux is made for */
  242.    
  243. if(request_irq(irq, &z8530_interrupt, SA_INTERRUPT, "SeaLevel", dev)<0)
  244. {
  245. printk(KERN_WARNING "sealevel: IRQ %d already in use.n", irq);
  246. goto fail1_1;
  247. }
  248. dev->irq=irq;
  249. dev->chanA.private=&b->dev[0];
  250. dev->chanB.private=&b->dev[1];
  251. dev->chanA.netdevice=b->dev[0].netdev.dev;
  252. dev->chanB.netdevice=b->dev[1].netdev.dev;
  253. dev->chanA.dev=dev;
  254. dev->chanB.dev=dev;
  255. dev->chanA.txdma=3;
  256. dev->chanA.rxdma=1;
  257. if(request_dma(dev->chanA.txdma, "SeaLevel (TX)")!=0)
  258. goto fail;
  259. if(request_dma(dev->chanA.rxdma, "SeaLevel (RX)")!=0)
  260. goto dmafail;
  261. save_flags(flags);
  262. cli();
  263. /*
  264.  * Begin normal initialise
  265.  */
  266.  
  267. if(z8530_init(dev)!=0)
  268. {
  269. printk(KERN_ERR "Z8530 series device not found.n");
  270. restore_flags(flags);
  271. goto dmafail2;
  272. }
  273. if(dev->type==Z85C30)
  274. {
  275. z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream);
  276. z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream);
  277. }
  278. else
  279. {
  280. z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230);
  281. z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream_85230);
  282. }
  283. /*
  284.  * Now we can take the IRQ
  285.  */
  286. restore_flags(flags);
  287. for(u=0; u<2; u++)
  288. {
  289. sv=&b->dev[u];
  290. sv->channel = u;
  291. if(dev_alloc_name(sv->chan->netdevice,"hdlc%d")>=0)
  292. {
  293. struct net_device *d=sv->chan->netdevice;
  294. /* 
  295.  * Initialise the PPP components
  296.  */
  297. sppp_attach(&sv->netdev);
  298. /*
  299.  * Local fields
  300.  */
  301. d->base_addr = iobase;
  302. d->irq = irq;
  303. d->priv = sv;
  304. d->init = NULL;
  305. d->open = sealevel_open;
  306. d->stop = sealevel_close;
  307. d->hard_start_xmit = sealevel_queue_xmit;
  308. d->get_stats = sealevel_get_stats;
  309. d->set_multicast_list = NULL;
  310. d->do_ioctl = sealevel_ioctl;
  311. d->neigh_setup = sealevel_neigh_setup_dev;
  312. d->set_mac_address = NULL;
  313. if(register_netdev(d)==-1)
  314. {
  315. printk(KERN_ERR "%s: unable to register device.n",
  316. d->name);
  317. goto fail_unit;
  318. }
  319. break;
  320. }
  321. }
  322. z8530_describe(dev, "I/O", iobase);
  323. dev->active=1;
  324. return b;
  325. fail_unit:
  326. if(u==1)
  327. unregister_netdev(b->dev[0].chan->netdevice);
  328. dmafail2:
  329. free_dma(dev->chanA.rxdma);
  330. dmafail:
  331. free_dma(dev->chanA.txdma);
  332. fail:
  333. free_irq(irq, dev);
  334. fail1_1:
  335. kfree(b->dev[1].netdev.dev);
  336. fail1_0:
  337. kfree(b->dev[0].netdev.dev);
  338. fail2:
  339. kfree(b);
  340. fail3:
  341. release_region(iobase,8);
  342. return NULL;
  343. }
  344. static void slvl_shutdown(struct slvl_board *b)
  345. {
  346. int u;
  347. z8530_shutdown(&b->board);
  348. for(u=0; u<2; u++)
  349. {
  350. sppp_detach(b->dev[u].netdev.dev);
  351. unregister_netdev(b->dev[u].netdev.dev);
  352. }
  353. free_irq(b->board.irq, &b->board);
  354. free_dma(b->board.chanA.rxdma);
  355. free_dma(b->board.chanA.txdma);
  356. /* DMA off on the card, drop DTR */
  357. outb(0, b->iobase);
  358. release_region(b->iobase, 8);
  359. }
  360. #ifdef MODULE
  361. static int io=0x238;
  362. static int txdma=1;
  363. static int rxdma=3;
  364. static int irq=5;
  365. static int slow=0;
  366. MODULE_PARM(io,"i");
  367. MODULE_PARM_DESC(io, "The I/O base of the Sealevel card");
  368. MODULE_PARM(txdma,"i");
  369. MODULE_PARM_DESC(txdma, "Transmit DMA channel");
  370. MODULE_PARM(rxdma,"i");
  371. MODULE_PARM_DESC(rxdma, "Receive DMA channel");
  372. MODULE_PARM(irq,"i");
  373. MODULE_PARM_DESC(irq, "The interrupt line setting for the SeaLevel card");
  374. MODULE_PARM(slow,"i");
  375. MODULE_PARM_DESC(slow, "Set this for an older Sealevel card such as the 4012");
  376. MODULE_AUTHOR("Alan Cox");
  377. MODULE_LICENSE("GPL");
  378. MODULE_DESCRIPTION("Modular driver for the SeaLevel 4021");
  379. static struct slvl_board *slvl_unit;
  380. int init_module(void)
  381. {
  382. printk(KERN_INFO "SeaLevel Z85230 Synchronous Driver v 0.01.n");
  383. printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.n");
  384. if((slvl_unit=slvl_init(io,irq, txdma, rxdma, slow))==NULL)
  385. return -ENODEV;
  386. return 0;
  387. }
  388. void cleanup_module(void)
  389. {
  390. if(slvl_unit)
  391. slvl_shutdown(slvl_unit);
  392. }
  393. #endif