1 /* 2 * Linux ARCnet driver - COM90xx chipset (IO-mapped buffers) 3 * 4 * Written 1997 by David Woodhouse. 5 * Written 1994-1999 by Avery Pennarun. 6 * Written 1999-2000 by Martin Mares <mj@ucw.cz>. 7 * Derived from skeleton.c by Donald Becker. 8 * 9 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com) 10 * for sponsoring the further development of this driver. 11 * 12 * ********************** 13 * 14 * The original copyright of skeleton.c was as follows: 15 * 16 * skeleton.c Written 1993 by Donald Becker. 17 * Copyright 1993 United States Government as represented by the 18 * Director, National Security Agency. This software may only be used 19 * and distributed according to the terms of the GNU General Public License as 20 * modified by SRC, incorporated herein by reference. 21 * 22 * ********************** 23 * 24 * For more details, see drivers/net/arcnet.c 25 * 26 * ********************** 27 */ 28 29 #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt 30 31 #include <linux/kernel.h> 32 #include <linux/module.h> 33 #include <linux/moduleparam.h> 34 #include <linux/ioport.h> 35 #include <linux/delay.h> 36 #include <linux/netdevice.h> 37 #include <linux/memblock.h> 38 #include <linux/init.h> 39 #include <linux/interrupt.h> 40 #include <linux/io.h> 41 42 #include "arcdevice.h" 43 #include "com9026.h" 44 45 /* Internal function declarations */ 46 47 static int com90io_found(struct net_device *dev); 48 static void com90io_command(struct net_device *dev, int command); 49 static int com90io_status(struct net_device *dev); 50 static void com90io_setmask(struct net_device *dev, int mask); 51 static int com90io_reset(struct net_device *dev, int really_reset); 52 static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset, 53 void *buf, int count); 54 static void com90io_copy_from_card(struct net_device *dev, int bufnum, 55 int offset, void *buf, int count); 56 57 /* Handy defines for ARCnet specific stuff */ 58 59 /* The number of low I/O ports used by the card. */ 60 #define ARCNET_TOTAL_SIZE 16 61 62 /**************************************************************************** 63 * * 64 * IO-mapped operation routines * 65 * * 66 ****************************************************************************/ 67 68 #undef ONE_AT_A_TIME_TX 69 #undef ONE_AT_A_TIME_RX 70 71 static u_char get_buffer_byte(struct net_device *dev, unsigned offset) 72 { 73 int ioaddr = dev->base_addr; 74 75 arcnet_outb(offset >> 8, ioaddr, COM9026_REG_W_ADDR_HI); 76 arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO); 77 78 return arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA); 79 } 80 81 #ifdef ONE_AT_A_TIME_TX 82 static void put_buffer_byte(struct net_device *dev, unsigned offset, 83 u_char datum) 84 { 85 int ioaddr = dev->base_addr; 86 87 arcnet_outb(offset >> 8, ioaddr, COM9026_REG_W_ADDR_HI); 88 arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO); 89 90 arcnet_outb(datum, ioaddr, COM9026_REG_RW_MEMDATA); 91 } 92 93 #endif 94 95 static void get_whole_buffer(struct net_device *dev, unsigned offset, 96 unsigned length, char *dest) 97 { 98 int ioaddr = dev->base_addr; 99 100 arcnet_outb((offset >> 8) | AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI); 101 arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO); 102 103 while (length--) 104 #ifdef ONE_AT_A_TIME_RX 105 *(dest++) = get_buffer_byte(dev, offset++); 106 #else 107 *(dest++) = arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA); 108 #endif 109 } 110 111 static void put_whole_buffer(struct net_device *dev, unsigned offset, 112 unsigned length, char *dest) 113 { 114 int ioaddr = dev->base_addr; 115 116 arcnet_outb((offset >> 8) | AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI); 117 arcnet_outb(offset & 0xff, ioaddr,COM9026_REG_W_ADDR_LO); 118 119 while (length--) 120 #ifdef ONE_AT_A_TIME_TX 121 put_buffer_byte(dev, offset++, *(dest++)); 122 #else 123 arcnet_outb(*(dest++), ioaddr, COM9026_REG_RW_MEMDATA); 124 #endif 125 } 126 127 /* We cannot probe for an IO mapped card either, although we can check that 128 * it's where we were told it was, and even autoirq 129 */ 130 static int __init com90io_probe(struct net_device *dev) 131 { 132 int ioaddr = dev->base_addr, status; 133 unsigned long airqmask; 134 135 if (BUGLVL(D_NORMAL)) { 136 pr_info("%s\n", "COM90xx IO-mapped mode support (by David Woodhouse et el.)"); 137 pr_info("E-mail me if you actually test this driver, please!\n"); 138 } 139 140 if (!ioaddr) { 141 arc_printk(D_NORMAL, dev, "No autoprobe for IO mapped cards; you must specify the base address!\n"); 142 return -ENODEV; 143 } 144 if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com90io probe")) { 145 arc_printk(D_INIT_REASONS, dev, "IO request_region %x-%x failed\n", 146 ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); 147 return -ENXIO; 148 } 149 if (arcnet_inb(ioaddr, COM9026_REG_R_STATUS) == 0xFF) { 150 arc_printk(D_INIT_REASONS, dev, "IO address %x empty\n", 151 ioaddr); 152 goto err_out; 153 } 154 arcnet_inb(ioaddr, COM9026_REG_R_RESET); 155 mdelay(RESETtime); 156 157 status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS); 158 159 if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) { 160 arc_printk(D_INIT_REASONS, dev, "Status invalid (%Xh)\n", 161 status); 162 goto err_out; 163 } 164 arc_printk(D_INIT_REASONS, dev, "Status after reset: %X\n", status); 165 166 arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear, 167 ioaddr, COM9026_REG_W_COMMAND); 168 169 arc_printk(D_INIT_REASONS, dev, "Status after reset acknowledged: %X\n", 170 status); 171 172 status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS); 173 174 if (status & RESETflag) { 175 arc_printk(D_INIT_REASONS, dev, "Eternal reset (status=%Xh)\n", 176 status); 177 goto err_out; 178 } 179 arcnet_outb((0x16 | IOMAPflag) & ~ENABLE16flag, 180 ioaddr, COM9026_REG_RW_CONFIG); 181 182 /* Read first loc'n of memory */ 183 184 arcnet_outb(AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI); 185 arcnet_outb(0, ioaddr, COM9026_REG_W_ADDR_LO); 186 187 status = arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA); 188 if (status != 0xd1) { 189 arc_printk(D_INIT_REASONS, dev, "Signature byte not found (%Xh instead).\n", 190 status); 191 goto err_out; 192 } 193 if (!dev->irq) { 194 /* if we do this, we're sure to get an IRQ since the 195 * card has just reset and the NORXflag is on until 196 * we tell it to start receiving. 197 */ 198 199 airqmask = probe_irq_on(); 200 arcnet_outb(NORXflag, ioaddr, COM9026_REG_W_INTMASK); 201 udelay(1); 202 arcnet_outb(0, ioaddr, COM9026_REG_W_INTMASK); 203 dev->irq = probe_irq_off(airqmask); 204 205 if ((int)dev->irq <= 0) { 206 arc_printk(D_INIT_REASONS, dev, "Autoprobe IRQ failed\n"); 207 goto err_out; 208 } 209 } 210 release_region(ioaddr, ARCNET_TOTAL_SIZE); /* end of probing */ 211 return com90io_found(dev); 212 213 err_out: 214 release_region(ioaddr, ARCNET_TOTAL_SIZE); 215 return -ENODEV; 216 } 217 218 /* Set up the struct net_device associated with this card. Called after 219 * probing succeeds. 220 */ 221 static int __init com90io_found(struct net_device *dev) 222 { 223 struct arcnet_local *lp; 224 int ioaddr = dev->base_addr; 225 int err; 226 227 /* Reserve the irq */ 228 if (request_irq(dev->irq, arcnet_interrupt, 0, 229 "arcnet (COM90xx-IO)", dev)) { 230 arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", dev->irq); 231 return -ENODEV; 232 } 233 /* Reserve the I/O region */ 234 if (!request_region(dev->base_addr, ARCNET_TOTAL_SIZE, 235 "arcnet (COM90xx-IO)")) { 236 free_irq(dev->irq, dev); 237 return -EBUSY; 238 } 239 240 lp = netdev_priv(dev); 241 lp->card_name = "COM90xx I/O"; 242 lp->hw.command = com90io_command; 243 lp->hw.status = com90io_status; 244 lp->hw.intmask = com90io_setmask; 245 lp->hw.reset = com90io_reset; 246 lp->hw.owner = THIS_MODULE; 247 lp->hw.copy_to_card = com90io_copy_to_card; 248 lp->hw.copy_from_card = com90io_copy_from_card; 249 250 lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag; 251 arcnet_outb(lp->config, ioaddr, COM9026_REG_RW_CONFIG); 252 253 /* get and check the station ID from offset 1 in shmem */ 254 255 dev->dev_addr[0] = get_buffer_byte(dev, 1); 256 257 err = register_netdev(dev); 258 if (err) { 259 arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) & ~IOMAPflag, 260 ioaddr, COM9026_REG_RW_CONFIG); 261 free_irq(dev->irq, dev); 262 release_region(dev->base_addr, ARCNET_TOTAL_SIZE); 263 return err; 264 } 265 266 arc_printk(D_NORMAL, dev, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n", 267 dev->dev_addr[0], dev->base_addr, dev->irq); 268 269 return 0; 270 } 271 272 /* Do a hardware reset on the card, and set up necessary registers. 273 * 274 * This should be called as little as possible, because it disrupts the 275 * token on the network (causes a RECON) and requires a significant delay. 276 * 277 * However, it does make sure the card is in a defined state. 278 */ 279 static int com90io_reset(struct net_device *dev, int really_reset) 280 { 281 struct arcnet_local *lp = netdev_priv(dev); 282 short ioaddr = dev->base_addr; 283 284 arc_printk(D_INIT, dev, "Resetting %s (status=%02Xh)\n", 285 dev->name, arcnet_inb(ioaddr, COM9026_REG_R_STATUS)); 286 287 if (really_reset) { 288 /* reset the card */ 289 arcnet_inb(ioaddr, COM9026_REG_R_RESET); 290 mdelay(RESETtime); 291 } 292 /* Set the thing to IO-mapped, 8-bit mode */ 293 lp->config = (0x1C | IOMAPflag) & ~ENABLE16flag; 294 arcnet_outb(lp->config, ioaddr, COM9026_REG_RW_CONFIG); 295 296 arcnet_outb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND); 297 /* clear flags & end reset */ 298 arcnet_outb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND); 299 300 /* verify that the ARCnet signature byte is present */ 301 if (get_buffer_byte(dev, 0) != TESTvalue) { 302 arc_printk(D_NORMAL, dev, "reset failed: TESTvalue not present.\n"); 303 return 1; 304 } 305 /* enable extended (512-byte) packets */ 306 arcnet_outb(CONFIGcmd | EXTconf, ioaddr, COM9026_REG_W_COMMAND); 307 /* done! return success. */ 308 return 0; 309 } 310 311 static void com90io_command(struct net_device *dev, int cmd) 312 { 313 short ioaddr = dev->base_addr; 314 315 arcnet_outb(cmd, ioaddr, COM9026_REG_W_COMMAND); 316 } 317 318 static int com90io_status(struct net_device *dev) 319 { 320 short ioaddr = dev->base_addr; 321 322 return arcnet_inb(ioaddr, COM9026_REG_R_STATUS); 323 } 324 325 static void com90io_setmask(struct net_device *dev, int mask) 326 { 327 short ioaddr = dev->base_addr; 328 329 arcnet_outb(mask, ioaddr, COM9026_REG_W_INTMASK); 330 } 331 332 static void com90io_copy_to_card(struct net_device *dev, int bufnum, 333 int offset, void *buf, int count) 334 { 335 TIME(dev, "put_whole_buffer", count, 336 put_whole_buffer(dev, bufnum * 512 + offset, count, buf)); 337 } 338 339 static void com90io_copy_from_card(struct net_device *dev, int bufnum, 340 int offset, void *buf, int count) 341 { 342 TIME(dev, "get_whole_buffer", count, 343 get_whole_buffer(dev, bufnum * 512 + offset, count, buf)); 344 } 345 346 static int io; /* use the insmod io= irq= shmem= options */ 347 static int irq; 348 static char device[9]; /* use eg. device=arc1 to change name */ 349 350 module_param_hw(io, int, ioport, 0); 351 module_param_hw(irq, int, irq, 0); 352 module_param_string(device, device, sizeof(device), 0); 353 MODULE_LICENSE("GPL"); 354 355 #ifndef MODULE 356 static int __init com90io_setup(char *s) 357 { 358 int ints[4]; 359 360 s = get_options(s, 4, ints); 361 if (!ints[0]) 362 return 0; 363 switch (ints[0]) { 364 default: /* ERROR */ 365 pr_err("Too many arguments\n"); 366 /* Fall through */ 367 case 2: /* IRQ */ 368 irq = ints[2]; 369 /* Fall through */ 370 case 1: /* IO address */ 371 io = ints[1]; 372 } 373 if (*s) 374 snprintf(device, sizeof(device), "%s", s); 375 return 1; 376 } 377 __setup("com90io=", com90io_setup); 378 #endif 379 380 static struct net_device *my_dev; 381 382 static int __init com90io_init(void) 383 { 384 struct net_device *dev; 385 int err; 386 387 dev = alloc_arcdev(device); 388 if (!dev) 389 return -ENOMEM; 390 391 dev->base_addr = io; 392 dev->irq = irq; 393 if (dev->irq == 2) 394 dev->irq = 9; 395 396 err = com90io_probe(dev); 397 398 if (err) { 399 free_netdev(dev); 400 return err; 401 } 402 403 my_dev = dev; 404 return 0; 405 } 406 407 static void __exit com90io_exit(void) 408 { 409 struct net_device *dev = my_dev; 410 int ioaddr = dev->base_addr; 411 412 unregister_netdev(dev); 413 414 /* In case the old driver is loaded later, 415 * set the thing back to MMAP mode 416 */ 417 arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) & ~IOMAPflag, 418 ioaddr, COM9026_REG_RW_CONFIG); 419 420 free_irq(dev->irq, dev); 421 release_region(dev->base_addr, ARCNET_TOTAL_SIZE); 422 free_netdev(dev); 423 } 424 425 module_init(com90io_init) 426 module_exit(com90io_exit) 427