4 * Comtrol SV11 card driver
6 * This is a slightly odd Z85230 synchronous driver. All you need to
11 * It supports DMA using two DMA channels in SYNC mode. The driver doesn't
12 * use these facilities
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
17 * The hardware does the bus handling to avoid the need for delays between
18 * touching control registers.
20 * Port B isnt wired (why - beats me)
23 #include <linux/module.h>
24 #include <linux/kernel.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>
36 #include <asm/byteorder.h>
44 struct z8530_dev sync
;
45 struct ppp_device netdev
;
50 * Network driver support routines
54 * Frame receive. Simple for our card as we do sync ppp and there
55 * is no funny garbage involved
58 static void hostess_input(struct z8530_channel
*c
, struct sk_buff
*skb
)
60 /* Drop the CRC - its not a good idea to try and negotiate it ;) */
61 skb_trim(skb
, skb
->len
-2);
62 skb
->protocol
=htons(ETH_P_WAN_PPP
);
63 skb
->mac
.raw
=skb
->data
;
64 skb
->dev
=c
->netdevice
;
66 * Send it to the PPP layer. We dont have time to process
73 * We've been placed in the UP state
76 static int hostess_open(struct net_device
*d
)
78 struct sv11_device
*sv11
=d
->priv
;
87 err
=z8530_sync_open(d
, &sv11
->sync
.chanA
);
90 err
=z8530_sync_dma_open(d
, &sv11
->sync
.chanA
);
93 err
=z8530_sync_txdma_open(d
, &sv11
->sync
.chanA
);
108 z8530_sync_close(d
, &sv11
->sync
.chanA
);
111 z8530_sync_dma_close(d
, &sv11
->sync
.chanA
);
114 z8530_sync_txdma_close(d
, &sv11
->sync
.chanA
);
119 sv11
->sync
.chanA
.rx_function
=hostess_input
;
129 static int hostess_close(struct net_device
*d
)
131 struct sv11_device
*sv11
=d
->priv
;
135 sv11
->sync
.chanA
.rx_function
=z8530_null_rx
;
148 z8530_sync_close(d
, &sv11
->sync
.chanA
);
151 z8530_sync_dma_close(d
, &sv11
->sync
.chanA
);
154 z8530_sync_txdma_close(d
, &sv11
->sync
.chanA
);
161 static int hostess_ioctl(struct net_device
*d
, struct ifreq
*ifr
, int cmd
)
163 /* struct sv11_device *sv11=d->priv;
164 z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
165 return sppp_do_ioctl(d
, ifr
,cmd
);
168 static struct enet_statistics
*hostess_get_stats(struct net_device
*d
)
170 struct sv11_device
*sv11
=d
->priv
;
172 return z8530_get_stats(&sv11
->sync
.chanA
);
178 * Passed PPP frames, fire them downwind.
181 static int hostess_queue_xmit(struct sk_buff
*skb
, struct net_device
*d
)
183 struct sv11_device
*sv11
=d
->priv
;
184 return z8530_queue_xmit(&sv11
->sync
.chanA
, skb
);
188 static int hostess_neigh_setup(struct neighbour
*n
)
190 if (n
->nud_state
== NUD_NONE
) {
191 n
->ops
= &arp_broken_ops
;
192 n
->output
= n
->ops
->output
;
197 static int hostess_neigh_setup_dev(struct net_device
*dev
, struct neigh_parms
*p
)
199 if (p
->tbl
->family
== AF_INET
) {
200 p
->neigh_setup
= hostess_neigh_setup
;
209 static int return_0(struct net_device
*d
)
217 * Description block for a Comtrol Hostess SV11 card
220 static struct sv11_device
*sv11_init(int iobase
, int irq
)
222 struct z8530_dev
*dev
;
223 struct sv11_device
*sv
;
228 * Get the needed I/O space
231 if(check_region(iobase
, 8))
233 printk(KERN_WARNING
"hostess: I/O 0x%X already in use.\n", iobase
);
236 request_region(iobase
, 8, "Comtrol SV11");
238 sv
=(struct sv11_device
*)kmalloc(sizeof(struct sv11_device
), GFP_KERNEL
);
242 memset(sv
, 0, sizeof(*sv
));
247 * Stuff in the I/O addressing
252 dev
->chanA
.ctrlio
=iobase
+1;
253 dev
->chanA
.dataio
=iobase
+3;
254 dev
->chanB
.ctrlio
=-1;
255 dev
->chanB
.dataio
=-1;
256 dev
->chanA
.irqs
=&z8530_nop
;
257 dev
->chanB
.irqs
=&z8530_nop
;
259 outb(0, iobase
+4); /* DMA off */
261 /* We want a fast IRQ for this device. Actually we'd like an even faster
262 IRQ ;) - This is one driver RtLinux is made for */
264 if(request_irq(irq
, &z8530_interrupt
, SA_INTERRUPT
, "Hostess SV/11", dev
)<0)
266 printk(KERN_WARNING
"hostess: IRQ %d already in use.\n", irq
);
271 dev
->chanA
.private=sv
;
272 dev
->chanA
.netdevice
=&sv
->netdev
.dev
;
280 * You can have DMA off or 1 and 3 thats the lot
285 outb(0x03|0x08, iobase
+4); /* DMA on */
286 if(request_dma(dev
->chanA
.txdma
, "Hostess SV/11 (TX)")!=0)
291 if(request_dma(dev
->chanA
.rxdma
, "Hostess SV/11 (RX)")!=0)
299 * Begin normal initialise
302 if(z8530_init(dev
)!=0)
304 printk(KERN_ERR
"Z8530 series device not found.\n");
307 z8530_channel_load(&dev
->chanB
, z8530_dead_port
);
308 if(dev
->type
==Z85C30
)
309 z8530_channel_load(&dev
->chanA
, z8530_hdlc_kilostream
);
311 z8530_channel_load(&dev
->chanA
, z8530_hdlc_kilostream_85230
);
313 restore_flags(flags
);
317 * Now we can take the IRQ
322 sprintf(sv
->name
,"hdlc%d", i
);
323 if(dev_get(sv
->name
)==NULL
)
325 struct net_device
*d
=dev
->chanA
.netdevice
;
328 * Initialise the PPP components
330 sppp_attach(&sv
->netdev
);
335 sprintf(sv
->name
,"hdlc%d", i
);
338 d
->base_addr
= iobase
;
343 d
->open
= hostess_open
;
344 d
->stop
= hostess_close
;
345 d
->hard_start_xmit
= hostess_queue_xmit
;
346 d
->get_stats
= hostess_get_stats
;
347 d
->set_multicast_list
= NULL
;
348 d
->do_ioctl
= hostess_ioctl
;
350 d
->neigh_setup
= hostess_neigh_setup_dev
;
355 d
->set_mac_address
= NULL
;
357 if(register_netdev(d
)==-1)
359 printk(KERN_ERR
"%s: unable to register device.\n",
364 z8530_describe(dev
, "I/O", iobase
);
371 free_dma(dev
->chanA
.rxdma
);
374 free_dma(dev
->chanA
.txdma
);
380 release_region(iobase
,8);
384 static void sv11_shutdown(struct sv11_device
*dev
)
386 sppp_detach(&dev
->netdev
.dev
);
387 z8530_shutdown(&dev
->sync
);
388 unregister_netdev(&dev
->netdev
.dev
);
389 free_irq(dev
->sync
.irq
, dev
);
393 free_dma(dev
->sync
.chanA
.rxdma
);
394 free_dma(dev
->sync
.chanA
.txdma
);
396 release_region(dev
->sync
.chanA
.ctrlio
-1, 8);
406 MODULE_PARM_DESC(io
, "The I/O base of the Comtrol Hostess SV11 card");
407 MODULE_PARM(dma
,"i");
408 MODULE_PARM_DESC(dma
, "Set this to 1 to use DMA1/DMA3 for TX/RX");
409 MODULE_PARM(irq
,"i");
410 MODULE_PARM_DESC(irq
, "The interrupt line setting for the Comtrol Hostess SV11 card");
412 MODULE_AUTHOR("Bulding Number Three Ltd");
413 MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
416 static struct sv11_device
*sv11_unit
;
418 int init_module(void)
420 printk(KERN_INFO
"SV-11 Z85230 Synchronous Driver v 0.02.\n");
421 printk(KERN_INFO
"(c) Copyright 1998, Building Number Three Ltd.\n");
422 if((sv11_unit
=sv11_init(io
,irq
))==NULL
)
427 void cleanup_module(void)
430 sv11_shutdown(sv11_unit
);