root/drivers/net/ac3200.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ac3200_probe
  2. ac_probe1
  3. ac_open
  4. ac_reset_8390
  5. ac_get_8390_hdr
  6. ac_block_input
  7. ac_block_output
  8. ac_close_card
  9. init_module
  10. cleanup_module

   1 /* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */
   2 /*
   3         Written 1993, 1994 by Donald Becker.
   4         Copyright 1993 United States Government as represented by the Director,
   5         National Security Agency.  This software may only be used and distributed
   6         according to the terms of the GNU Public License as modified by SRC,
   7         incorporated herein by reference.
   8 
   9         The author may be reached as becker@cesdis.gsfc.nasa.gov, or
  10     C/O Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
  11 
  12         This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN
  13         Adapter.  The programming information is from the users manual, as related
  14         by glee@ardnassak.math.clemson.edu.
  15   */
  16 
  17 static const char *version =
  18         "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
  19 
  20 #include <linux/module.h>
  21 
  22 #include <linux/kernel.h>
  23 #include <linux/sched.h>
  24 #include <linux/errno.h>
  25 #include <linux/string.h>
  26 #include <linux/netdevice.h>
  27 #include <linux/etherdevice.h>
  28 
  29 #include <asm/system.h>
  30 #include <asm/io.h>
  31 
  32 #include "8390.h"
  33 
  34 /* Offsets from the base address. */
  35 #define AC_NIC_BASE             0x00
  36 #define AC_SA_PROM              0x16                    /* The station address PROM. */
  37 #define  AC_ADDR0                0x00                   /* Prefix station address values. */
  38 #define  AC_ADDR1                0x40                   /* !!!!These are just guesses!!!! */
  39 #define  AC_ADDR2                0x90
  40 #define AC_ID_PORT              0xC80
  41 #define AC_EISA_ID               0x0110d305
  42 #define AC_RESET_PORT   0xC84
  43 #define  AC_RESET                0x00
  44 #define  AC_ENABLE               0x01
  45 #define AC_CONFIG               0xC90   /* The configuration port. */
  46 
  47 #define AC_IO_EXTENT 0x10               /* IS THIS REALLY TRUE ??? */
  48                                 /* Actually accessed is:
  49                                                                  * AC_NIC_BASE (0-15)
  50                                                                  * AC_SA_PROM (0-5)
  51                                                                  * AC_ID_PORT (0-3)
  52                                                                  * AC_RESET_PORT
  53                                                                  * AC_CONFIG
  54                                                                  */
  55 
  56 /* Decoding of the configuration register. */
  57 static unsigned char config2irqmap[8] = {15, 12, 11, 10, 9, 7, 5, 3};
  58 static int addrmap[8] =
  59 {0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000,  0xD0000, 0 };
  60 static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
  61 
  62 #define config2irq(configval)   config2irqmap[((configval) >> 3) & 7]
  63 #define config2mem(configval)   addrmap[(configval) & 7]
  64 #define config2name(configval)  port_name[((configval) >> 6) & 3]
  65 
  66 /* First and last 8390 pages. */
  67 #define AC_START_PG             0x00    /* First page of 8390 TX buffer */
  68 #define AC_STOP_PG              0x80    /* Last page +1 of the 8390 RX ring */
  69 
  70 int ac3200_probe(struct device *dev);
  71 static int ac_probe1(int ioaddr, struct device *dev);
  72 
  73 static int ac_open(struct device *dev);
  74 static void ac_reset_8390(struct device *dev);
  75 static void ac_block_input(struct device *dev, int count,
  76                                         struct sk_buff *skb, int ring_offset);
  77 static void ac_block_output(struct device *dev, const int count,
  78                                                         const unsigned char *buf, const int start_page);
  79 static void ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
  80                                         int ring_page);
  81 
  82 static int ac_close_card(struct device *dev);
  83 
  84 
  85 /*      Probe for the AC3200.
  86 
  87         The AC3200 can be identified by either the EISA configuration registers,
  88         or the unique value in the station address PROM.
  89         */
  90 
  91 int ac3200_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93         unsigned short ioaddr = dev->base_addr;
  94 
  95         if (ioaddr > 0x1ff)             /* Check a single specified location. */
  96                 return ac_probe1(ioaddr, dev);
  97         else if (ioaddr > 0)            /* Don't probe at all. */
  98                 return ENXIO;
  99 
 100         /* If you have a pre 0.99pl15 machine you should delete this line. */
 101         if ( ! EISA_bus)
 102                 return ENXIO;
 103 
 104         for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
 105                 if (check_region(ioaddr, AC_IO_EXTENT))
 106                         continue;
 107                 if (ac_probe1(ioaddr, dev) == 0)
 108                         return 0;
 109         }
 110 
 111         return ENODEV;
 112 }
 113 
 114 static int ac_probe1(int ioaddr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 115 {
 116         int i;
 117 
 118 #ifndef final_version
 119         printk("AC3200 ethercard probe at %#3x:", ioaddr);
 120 
 121         for(i = 0; i < 6; i++)
 122                 printk(" %02x", inb(ioaddr + AC_SA_PROM + i));
 123 #endif
 124 
 125         /* !!!!The values of AC_ADDRn (see above) should be corrected when we
 126            find out the correct station address prefix!!!! */
 127         if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
 128                 || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
 129                 || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
 130 #ifndef final_version
 131                 printk(" not found (invalid prefix).\n");
 132 #endif
 133                 return ENODEV;
 134         }
 135 
 136         /* The correct probe method is to check the EISA ID. */
 137         for (i = 0; i < 4; i++)
 138                 if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
 139                         printk("EISA ID mismatch, %8x vs %8x.\n",
 140                                    inl(ioaddr + AC_EISA_ID), AC_EISA_ID); 
 141                         return ENODEV;
 142                 }
 143 
 144 
 145         /* We should have a "dev" from Space.c or the static module table. */
 146         if (dev == NULL) {
 147                 printk("ac3200.c: Passed a NULL device.\n");
 148                 dev = init_etherdev(0, 0);
 149         }
 150 
 151         for(i = 0; i < ETHER_ADDR_LEN; i++)
 152                 dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i);
 153 
 154 #ifndef final_version
 155         printk("\nAC3200 ethercard configuration register is %#02x,"
 156                    " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
 157                    inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
 158                    inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
 159 #endif
 160 
 161         /* Assign and allocate the interrupt now. */
 162         if (dev->irq == 0)
 163                 dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
 164         else if (dev->irq == 2)
 165                 dev->irq = 9;
 166 
 167         if (request_irq(dev->irq, ei_interrupt, 0, "ac3200")) {
 168                 printk (" unable to get IRQ %d.\n", dev->irq);
 169                 return EAGAIN;
 170         }
 171 
 172         /* Allocate dev->priv and fill in 8390 specific dev fields. */
 173         if (ethdev_init(dev)) {
 174                 printk (" unable to allocate memory for dev->priv.\n");
 175                 free_irq(dev->irq);
 176                 return -ENOMEM;
 177         }
 178 
 179         request_region(ioaddr, AC_IO_EXTENT, "ac3200");
 180 
 181         dev->base_addr = ioaddr;
 182 
 183 #ifdef notyet
 184         if (dev->mem_start)     {               /* Override the value from the board. */
 185                 for (i = 0; i < 7; i++)
 186                         if (addrmap[i] == dev->mem_start)
 187                                 break;
 188                 if (i >= 7)
 189                         i = 0;
 190                 outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
 191         }
 192 #endif
 193 
 194         dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
 195         dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
 196         dev->rmem_start = dev->mem_start + TX_PAGES*256;
 197         dev->mem_end = dev->rmem_end = dev->mem_start
 198                 + (AC_STOP_PG - AC_START_PG)*256;
 199 
 200         ei_status.name = "AC3200";
 201         ei_status.tx_start_page = AC_START_PG;
 202         ei_status.rx_start_page = AC_START_PG + TX_PAGES;
 203         ei_status.stop_page = AC_STOP_PG;
 204         ei_status.word16 = 1;
 205 
 206         printk("\n%s: AC3200 at %#x, IRQ %d, %s port, shared memory %#lx-%#lx.\n",
 207                    dev->name, ioaddr, dev->irq, port_name[dev->if_port],
 208                    dev->mem_start, dev->mem_end-1);
 209 
 210         if (ei_debug > 0)
 211                 printk(version);
 212 
 213         ei_status.reset_8390 = &ac_reset_8390;
 214         ei_status.block_input = &ac_block_input;
 215         ei_status.block_output = &ac_block_output;
 216         ei_status.get_8390_hdr = &ac_get_8390_hdr;
 217 
 218         dev->open = &ac_open;
 219         dev->stop = &ac_close_card;
 220         NS8390_init(dev, 0);
 221         return 0;
 222 }
 223 
 224 static int ac_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 225 {
 226 #ifdef notyet
 227         /* Someday we may enable the IRQ and shared memory here. */
 228         int ioaddr = dev->base_addr;
 229 
 230         if (request_irq(dev->irq, ei_interrupt, 0, "ac3200"))
 231                 return -EAGAIN;
 232 #endif
 233 
 234         ei_open(dev);
 235 
 236         MOD_INC_USE_COUNT;
 237 
 238         return 0;
 239 }
 240 
 241 static void ac_reset_8390(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 242 {
 243         ushort ioaddr = dev->base_addr;
 244 
 245         outb(AC_RESET, ioaddr + AC_RESET_PORT);
 246         if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
 247 
 248         ei_status.txing = 0;
 249         outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
 250         if (ei_debug > 1) printk("reset done\n");
 251 
 252         return;
 253 }
 254 
 255 /* Grab the 8390 specific header. Similar to the block_input routine, but
 256    we don't need to be concerned with ring wrap as the header will be at
 257    the start of a page, so we optimize accordingly. */
 258 
 259 static void
 260 ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262         unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8);
 263         memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 264 }
 265 
 266 /*  Block input and output are easy on shared memory ethercards, the only
 267         complication is when the ring buffer wraps. */
 268 
 269 static void ac_block_input(struct device *dev, int count, struct sk_buff *skb,
     /* [previous][next][first][last][top][bottom][index][help] */
 270                                                   int ring_offset)
 271 {
 272         unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
 273 
 274         if (xfer_start + count > dev->rmem_end) {
 275                 /* We must wrap the input move. */
 276                 int semi_count = dev->rmem_end - xfer_start;
 277                 memcpy_fromio(skb->data, xfer_start, semi_count);
 278                 count -= semi_count;
 279                 memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
 280         } else {
 281                 /* Packet is in one chunk -- we can copy + cksum. */
 282                 eth_io_copy_and_sum(skb, xfer_start, count, 0);
 283         }
 284 }
 285 
 286 static void ac_block_output(struct device *dev, int count,
     /* [previous][next][first][last][top][bottom][index][help] */
 287                                                         const unsigned char *buf, int start_page)
 288 {
 289         unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
 290 
 291         memcpy_toio(shmem, buf, count);
 292 }
 293 
 294 static int ac_close_card(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 295 {
 296         dev->start = 0;
 297         dev->tbusy = 1;
 298 
 299         if (ei_debug > 1)
 300                 printk("%s: Shutting down ethercard.\n", dev->name);
 301 
 302 #ifdef notyet
 303         /* We should someday disable shared memory and interrupts. */
 304         outb(0x00, ioaddr + 6); /* Disable interrupts. */
 305         free_irq(dev->irq);
 306         irq2dev_map[dev->irq] = 0;
 307 #endif
 308 
 309         ei_close(dev);
 310 
 311         MOD_DEC_USE_COUNT;
 312 
 313         return 0;
 314 }
 315 
 316 #ifdef MODULE
 317 #define MAX_AC32_CARDS  4       /* Max number of AC32 cards per module */
 318 #define NAMELEN         8       /* # of chars for storing dev->name */
 319 static char namelist[NAMELEN * MAX_AC32_CARDS] = { 0, };
 320 static struct device dev_ac32[MAX_AC32_CARDS] = {
 321         {
 322                 NULL,           /* assign a chunk of namelist[] below */
 323                 0, 0, 0, 0,
 324                 0, 0,
 325                 0, 0, 0, NULL, NULL
 326         },
 327 };
 328 
 329 static int io[MAX_AC32_CARDS] = { 0, };
 330 static int irq[MAX_AC32_CARDS]  = { 0, };
 331 static int mem[MAX_AC32_CARDS] = { 0, };
 332 
 333 int
 334 init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 335 {
 336         int this_dev, found = 0;
 337 
 338         for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
 339                 struct device *dev = &dev_ac32[this_dev];
 340                 dev->name = namelist+(NAMELEN*this_dev);
 341                 dev->irq = irq[this_dev];
 342                 dev->base_addr = io[this_dev];
 343                 dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
 344                 dev->init = ac3200_probe;
 345                 /* Default is to only install one card. */
 346                 if (io[this_dev] == 0 && this_dev != 0) break;
 347                 if (register_netdev(dev) != 0) {
 348                         printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
 349                         if (found != 0) return 0;       /* Got at least one. */
 350                         return -ENXIO;
 351                 }
 352                 found++;
 353         }
 354 
 355         return 0;
 356 }
 357 
 358 void
 359 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 360 {
 361         int this_dev;
 362 
 363         for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
 364                 struct device *dev = &dev_ac32[this_dev];
 365                 if (dev->priv != NULL) {
 366                         kfree(dev->priv);
 367                         dev->priv = NULL;
 368                         /* Someday free_irq + irq2dev may be in ac_close_card() */
 369                         free_irq(dev->irq);
 370                         irq2dev_map[dev->irq] = NULL;
 371                         release_region(dev->base_addr, AC_IO_EXTENT);
 372                         unregister_netdev(dev);
 373                 }
 374         }
 375 }
 376 #endif /* MODULE */
 377 
 378 /*
 379  * Local variables:
 380  * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c ac3200.c"
 381  *  version-control: t
 382  *  kept-new-versions: 5
 383  *  tab-width: 4
 384  * End:
 385  */

/* [previous][next][first][last][top][bottom][index][help] */