^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Linux ARCnet driver - "RIM I" (entirely mem-mapped) cards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Written 1994-1999 by Avery Pennarun.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Derived from skeleton.c by Donald Becker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * for sponsoring the further development of this driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * **********************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * The original copyright of skeleton.c was as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * skeleton.c Written 1993 by Donald Becker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Copyright 1993 United States Government as represented by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Director, National Security Agency. This software may only be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * and distributed according to the terms of the GNU General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * modified by SRC, incorporated herein by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * **********************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * For more details, see drivers/net/arcnet.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * **********************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "arcdevice.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "com9026.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Internal function declarations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int arcrimi_probe(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int arcrimi_found(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static void arcrimi_command(struct net_device *dev, int command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int arcrimi_status(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static void arcrimi_setmask(struct net_device *dev, int mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int arcrimi_reset(struct net_device *dev, int really_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void *buf, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static void arcrimi_copy_from_card(struct net_device *dev, int bufnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int offset, void *buf, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Handy defines for ARCnet specific stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Amount of I/O memory used by the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define BUFFER_SIZE (512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MIRROR_SIZE (BUFFER_SIZE * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* We cannot probe for a RIM I card; one reason is I don't know how to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * them. In fact, we can't even get their node ID automatically. So, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * need to be passed a specific shmem address, IRQ, and node ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int __init arcrimi_probe(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (BUGLVL(D_NORMAL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) pr_info("%s\n", "RIM I (entirely mem-mapped) support");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) pr_info("E-mail me if you actually test the RIM I driver, please!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) pr_info("Given: node %02Xh, shmem %lXh, irq %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) dev->dev_addr[0], dev->mem_start, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (dev->mem_start <= 0 || dev->irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (BUGLVL(D_NORMAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) pr_err("No autoprobe for RIM I; you must specify the shmem and irq!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (dev->dev_addr[0] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (BUGLVL(D_NORMAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) pr_err("You need to specify your card's station ID!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Grab the memory region at mem_start for MIRROR_SIZE bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Later in arcrimi_found() the real size will be determined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * and this reserve will be released and the correct size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * will be taken.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (BUGLVL(D_NORMAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) pr_notice("Card memory already allocated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return arcrimi_found(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int check_mirror(unsigned long addr, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void __iomem *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int res = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!request_mem_region(addr, size, "arcnet (90xx)"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) p = ioremap(addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) iounmap(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) release_mem_region(addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Set up the struct net_device associated with this card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Called after probing succeeds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int __init arcrimi_found(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct arcnet_local *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned long first_mirror, last_mirror, shmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) void __iomem *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int mirror_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) p = ioremap(dev->mem_start, MIRROR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) release_mem_region(dev->mem_start, MIRROR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) arc_printk(D_NORMAL, dev, "Can't ioremap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* reserve the irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) iounmap(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) release_mem_region(dev->mem_start, MIRROR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) shmem = dev->mem_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) arcnet_writeb(TESTvalue, p, COM9026_REG_W_INTMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) arcnet_writeb(TESTvalue, p, COM9026_REG_W_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* actually the station/node ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* find the real shared memory start/end points, including mirrors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* guess the actual size of one "memory mirror" - the number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * bytes between copies of the shared memory. On most cards, it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * 2k (or there are no mirrors at all) but on some, it's 4k.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) mirror_size = MIRROR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mirror_size = 2 * MIRROR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) first_mirror = shmem - mirror_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) while (check_mirror(first_mirror, mirror_size) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) first_mirror -= mirror_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) first_mirror += mirror_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) last_mirror = shmem + mirror_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) while (check_mirror(last_mirror, mirror_size) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) last_mirror += mirror_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) last_mirror -= mirror_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) dev->mem_start = first_mirror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev->mem_end = last_mirror + MIRROR_SIZE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* initialize the rest of the device structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) lp->card_name = "RIM I";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) lp->hw.command = arcrimi_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) lp->hw.status = arcrimi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) lp->hw.intmask = arcrimi_setmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) lp->hw.reset = arcrimi_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) lp->hw.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) lp->hw.copy_to_card = arcrimi_copy_to_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) lp->hw.copy_from_card = arcrimi_copy_from_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* re-reserve the memory region - arcrimi_probe() alloced this reqion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * but didn't know the real size. Free that region and then re-get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * with the correct size. There is a VERY slim chance this could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) iounmap(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) release_mem_region(shmem, MIRROR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!request_mem_region(dev->mem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) dev->mem_end - dev->mem_start + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) "arcnet (90xx)")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) arc_printk(D_NORMAL, dev, "Card memory already allocated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) goto err_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) lp->mem_start = ioremap(dev->mem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) dev->mem_end - dev->mem_start + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (!lp->mem_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) arc_printk(D_NORMAL, dev, "Can't remap device memory!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) goto err_release_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* get and check the station ID from offset 1 in shmem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) dev->dev_addr[0] = arcnet_readb(lp->mem_start, COM9026_REG_R_STATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) arc_printk(D_NORMAL, dev, "ARCnet RIM I: station %02Xh found at IRQ %d, ShMem %lXh (%ld*%d bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) dev->dev_addr[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dev->irq, dev->mem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) (dev->mem_end - dev->mem_start + 1) / mirror_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) mirror_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) goto err_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) err_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) iounmap(lp->mem_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) err_release_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) err_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) free_irq(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Do a hardware reset on the card, and set up necessary registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * This should be called as little as possible, because it disrupts the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * token on the network (causes a RECON) and requires a significant delay.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * However, it does make sure the card is in a defined state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int arcrimi_reset(struct net_device *dev, int really_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct arcnet_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) void __iomem *ioaddr = lp->mem_start + 0x800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) arc_printk(D_INIT, dev, "Resetting %s (status=%02Xh)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dev->name, arcnet_readb(ioaddr, COM9026_REG_R_STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (really_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) arcnet_writeb(TESTvalue, ioaddr, -0x800); /* fake reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* clear flags & end reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) arcnet_writeb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) arcnet_writeb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* enable extended (512-byte) packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) arcnet_writeb(CONFIGcmd | EXTconf, ioaddr, COM9026_REG_W_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* done! return success. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void arcrimi_setmask(struct net_device *dev, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct arcnet_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) void __iomem *ioaddr = lp->mem_start + 0x800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) arcnet_writeb(mask, ioaddr, COM9026_REG_W_INTMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int arcrimi_status(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct arcnet_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) void __iomem *ioaddr = lp->mem_start + 0x800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return arcnet_readb(ioaddr, COM9026_REG_R_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void arcrimi_command(struct net_device *dev, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct arcnet_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) void __iomem *ioaddr = lp->mem_start + 0x800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) arcnet_writeb(cmd, ioaddr, COM9026_REG_W_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) void *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct arcnet_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) TIME(dev, "memcpy_toio", count, memcpy_toio(memaddr, buf, count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void arcrimi_copy_from_card(struct net_device *dev, int bufnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int offset, void *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct arcnet_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) TIME(dev, "memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static int node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static int io; /* use the insmod io= irq= node= options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static char device[9]; /* use eg. device=arc1 to change name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) module_param(node, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) module_param(io, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) module_param(irq, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) module_param_string(device, device, sizeof(device), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static struct net_device *my_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int __init arc_rimi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) dev = alloc_arcdev(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (node && node != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dev->dev_addr[0] = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) dev->mem_start = io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dev->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (dev->irq == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) dev->irq = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (arcrimi_probe(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) my_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static void __exit arc_rimi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct net_device *dev = my_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct arcnet_local *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) iounmap(lp->mem_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) free_irq(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) #ifndef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static int __init arcrimi_setup(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int ints[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) s = get_options(s, 8, ints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!ints[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) switch (ints[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) default: /* ERROR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) pr_err("Too many arguments\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case 3: /* Node ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) node = ints[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case 2: /* IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) irq = ints[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case 1: /* IO address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) io = ints[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (*s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) snprintf(device, sizeof(device), "%s", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) __setup("arcrimi=", arcrimi_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) #endif /* MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) module_init(arc_rimi_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) module_exit(arc_rimi_exit)