Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.14 339 lines 7.2 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 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 isn't wired (why - beats me) 19 * 20 * Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl> 21 */ 22 23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 24 25#include <linux/module.h> 26#include <linux/kernel.h> 27#include <linux/mm.h> 28#include <linux/net.h> 29#include <linux/skbuff.h> 30#include <linux/netdevice.h> 31#include <linux/if_arp.h> 32#include <linux/delay.h> 33#include <linux/hdlc.h> 34#include <linux/ioport.h> 35#include <linux/slab.h> 36#include <net/arp.h> 37 38#include <asm/irq.h> 39#include <asm/io.h> 40#include <asm/dma.h> 41#include <asm/byteorder.h> 42#include "z85230.h" 43 44static int dma; 45 46/* Network driver support routines 47 */ 48 49static inline struct z8530_dev *dev_to_sv(struct net_device *dev) 50{ 51 return (struct z8530_dev *)dev_to_hdlc(dev)->priv; 52} 53 54/* Frame receive. Simple for our card as we do HDLC and there 55 * is no funny garbage involved 56 */ 57 58static void hostess_input(struct z8530_channel *c, struct sk_buff *skb) 59{ 60 /* Drop the CRC - it's not a good idea to try and negotiate it ;) */ 61 skb_trim(skb, skb->len - 2); 62 skb->protocol = hdlc_type_trans(skb, c->netdevice); 63 skb_reset_mac_header(skb); 64 skb->dev = c->netdevice; 65 /* Send it to the PPP layer. We don't have time to process 66 * it right now. 67 */ 68 netif_rx(skb); 69} 70 71/* We've been placed in the UP state 72 */ 73 74static int hostess_open(struct net_device *d) 75{ 76 struct z8530_dev *sv11 = dev_to_sv(d); 77 int err = -1; 78 79 /* Link layer up 80 */ 81 switch (dma) { 82 case 0: 83 err = z8530_sync_open(d, &sv11->chanA); 84 break; 85 case 1: 86 err = z8530_sync_dma_open(d, &sv11->chanA); 87 break; 88 case 2: 89 err = z8530_sync_txdma_open(d, &sv11->chanA); 90 break; 91 } 92 93 if (err) 94 return err; 95 96 err = hdlc_open(d); 97 if (err) { 98 switch (dma) { 99 case 0: 100 z8530_sync_close(d, &sv11->chanA); 101 break; 102 case 1: 103 z8530_sync_dma_close(d, &sv11->chanA); 104 break; 105 case 2: 106 z8530_sync_txdma_close(d, &sv11->chanA); 107 break; 108 } 109 return err; 110 } 111 sv11->chanA.rx_function = hostess_input; 112 113 /* 114 * Go go go 115 */ 116 117 netif_start_queue(d); 118 return 0; 119} 120 121static int hostess_close(struct net_device *d) 122{ 123 struct z8530_dev *sv11 = dev_to_sv(d); 124 /* Discard new frames 125 */ 126 sv11->chanA.rx_function = z8530_null_rx; 127 128 hdlc_close(d); 129 netif_stop_queue(d); 130 131 switch (dma) { 132 case 0: 133 z8530_sync_close(d, &sv11->chanA); 134 break; 135 case 1: 136 z8530_sync_dma_close(d, &sv11->chanA); 137 break; 138 case 2: 139 z8530_sync_txdma_close(d, &sv11->chanA); 140 break; 141 } 142 return 0; 143} 144 145static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) 146{ 147 return hdlc_ioctl(d, ifr, cmd); 148} 149 150/* Passed network frames, fire them downwind. 151 */ 152 153static netdev_tx_t hostess_queue_xmit(struct sk_buff *skb, 154 struct net_device *d) 155{ 156 return z8530_queue_xmit(&dev_to_sv(d)->chanA, skb); 157} 158 159static int hostess_attach(struct net_device *dev, unsigned short encoding, 160 unsigned short parity) 161{ 162 if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT) 163 return 0; 164 return -EINVAL; 165} 166 167/* Description block for a Comtrol Hostess SV11 card 168 */ 169 170static const struct net_device_ops hostess_ops = { 171 .ndo_open = hostess_open, 172 .ndo_stop = hostess_close, 173 .ndo_start_xmit = hdlc_start_xmit, 174 .ndo_do_ioctl = hostess_ioctl, 175}; 176 177static struct z8530_dev *sv11_init(int iobase, int irq) 178{ 179 struct z8530_dev *sv; 180 struct net_device *netdev; 181 /* Get the needed I/O space 182 */ 183 184 if (!request_region(iobase, 8, "Comtrol SV11")) { 185 pr_warn("I/O 0x%X already in use\n", iobase); 186 return NULL; 187 } 188 189 sv = kzalloc(sizeof(struct z8530_dev), GFP_KERNEL); 190 if (!sv) 191 goto err_kzalloc; 192 193 /* Stuff in the I/O addressing 194 */ 195 196 sv->active = 0; 197 198 sv->chanA.ctrlio = iobase + 1; 199 sv->chanA.dataio = iobase + 3; 200 sv->chanB.ctrlio = -1; 201 sv->chanB.dataio = -1; 202 sv->chanA.irqs = &z8530_nop; 203 sv->chanB.irqs = &z8530_nop; 204 205 outb(0, iobase + 4); /* DMA off */ 206 207 /* We want a fast IRQ for this device. Actually we'd like an even faster 208 * IRQ ;) - This is one driver RtLinux is made for 209 */ 210 211 if (request_irq(irq, z8530_interrupt, 0, 212 "Hostess SV11", sv) < 0) { 213 pr_warn("IRQ %d already in use\n", irq); 214 goto err_irq; 215 } 216 217 sv->irq = irq; 218 sv->chanA.private = sv; 219 sv->chanA.dev = sv; 220 sv->chanB.dev = sv; 221 222 if (dma) { 223 /* You can have DMA off or 1 and 3 thats the lot 224 * on the Comtrol. 225 */ 226 sv->chanA.txdma = 3; 227 sv->chanA.rxdma = 1; 228 outb(0x03 | 0x08, iobase + 4); /* DMA on */ 229 if (request_dma(sv->chanA.txdma, "Hostess SV/11 (TX)")) 230 goto err_txdma; 231 232 if (dma == 1) 233 if (request_dma(sv->chanA.rxdma, "Hostess SV/11 (RX)")) 234 goto err_rxdma; 235 } 236 237 /* Kill our private IRQ line the hostess can end up chattering 238 * until the configuration is set 239 */ 240 disable_irq(irq); 241 242 /* Begin normal initialise 243 */ 244 245 if (z8530_init(sv)) { 246 pr_err("Z8530 series device not found\n"); 247 enable_irq(irq); 248 goto free_dma; 249 } 250 z8530_channel_load(&sv->chanB, z8530_dead_port); 251 if (sv->type == Z85C30) 252 z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream); 253 else 254 z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream_85230); 255 256 enable_irq(irq); 257 258 /* Now we can take the IRQ 259 */ 260 261 sv->chanA.netdevice = netdev = alloc_hdlcdev(sv); 262 if (!netdev) 263 goto free_dma; 264 265 dev_to_hdlc(netdev)->attach = hostess_attach; 266 dev_to_hdlc(netdev)->xmit = hostess_queue_xmit; 267 netdev->netdev_ops = &hostess_ops; 268 netdev->base_addr = iobase; 269 netdev->irq = irq; 270 271 if (register_hdlc_device(netdev)) { 272 pr_err("unable to register HDLC device\n"); 273 free_netdev(netdev); 274 goto free_dma; 275 } 276 277 z8530_describe(sv, "I/O", iobase); 278 sv->active = 1; 279 return sv; 280 281free_dma: 282 if (dma == 1) 283 free_dma(sv->chanA.rxdma); 284err_rxdma: 285 if (dma) 286 free_dma(sv->chanA.txdma); 287err_txdma: 288 free_irq(irq, sv); 289err_irq: 290 kfree(sv); 291err_kzalloc: 292 release_region(iobase, 8); 293 return NULL; 294} 295 296static void sv11_shutdown(struct z8530_dev *dev) 297{ 298 unregister_hdlc_device(dev->chanA.netdevice); 299 z8530_shutdown(dev); 300 free_irq(dev->irq, dev); 301 if (dma) { 302 if (dma == 1) 303 free_dma(dev->chanA.rxdma); 304 free_dma(dev->chanA.txdma); 305 } 306 release_region(dev->chanA.ctrlio - 1, 8); 307 free_netdev(dev->chanA.netdevice); 308 kfree(dev); 309} 310 311static int io = 0x200; 312static int irq = 9; 313 314module_param_hw(io, int, ioport, 0); 315MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card"); 316module_param_hw(dma, int, dma, 0); 317MODULE_PARM_DESC(dma, "Set this to 1 to use DMA1/DMA3 for TX/RX"); 318module_param_hw(irq, int, irq, 0); 319MODULE_PARM_DESC(irq, "The interrupt line setting for the Comtrol Hostess SV11 card"); 320 321MODULE_AUTHOR("Alan Cox"); 322MODULE_LICENSE("GPL"); 323MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11"); 324 325static struct z8530_dev *sv11_unit; 326 327int init_module(void) 328{ 329 sv11_unit = sv11_init(io, irq); 330 if (!sv11_unit) 331 return -ENODEV; 332 return 0; 333} 334 335void cleanup_module(void) 336{ 337 if (sv11_unit) 338 sv11_shutdown(sv11_unit); 339}