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