hostess_sv11.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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