root/drivers/net/ethernet/amd/am79c961a.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. write_rreg
  2. read_rreg
  3. write_ireg
  4. read_ireg
  5. am_writebuffer
  6. am_readbuffer
  7. am79c961_ramtest
  8. am79c961_mc_hash
  9. am79c961_get_rx_mode
  10. am79c961_init_for_open
  11. am79c961_timer
  12. am79c961_open
  13. am79c961_close
  14. am79c961_setmulticastlist
  15. am79c961_timeout
  16. am79c961_sendpacket
  17. am79c961_rx
  18. am79c961_tx
  19. am79c961_interrupt
  20. am79c961_poll_controller
  21. am79c961_hw_init
  22. am79c961_banner
  23. am79c961_probe
  24. am79c961_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  linux/drivers/net/ethernet/amd/am79c961a.c
   4  *
   5  *  by Russell King <rmk@arm.linux.org.uk> 1995-2001.
   6  *
   7  * Derived from various things including skeleton.c
   8  *
   9  * This is a special driver for the am79c961A Lance chip used in the
  10  * Intel (formally Digital Equipment Corp) EBSA110 platform.  Please
  11  * note that this can not be built as a module (it doesn't make sense).
  12  */
  13 #include <linux/kernel.h>
  14 #include <linux/types.h>
  15 #include <linux/interrupt.h>
  16 #include <linux/ioport.h>
  17 #include <linux/slab.h>
  18 #include <linux/string.h>
  19 #include <linux/errno.h>
  20 #include <linux/netdevice.h>
  21 #include <linux/etherdevice.h>
  22 #include <linux/delay.h>
  23 #include <linux/init.h>
  24 #include <linux/crc32.h>
  25 #include <linux/bitops.h>
  26 #include <linux/platform_device.h>
  27 #include <linux/io.h>
  28 
  29 #include <mach/hardware.h>
  30 
  31 #define TX_BUFFERS 15
  32 #define RX_BUFFERS 25
  33 
  34 #include "am79c961a.h"
  35 
  36 static irqreturn_t
  37 am79c961_interrupt (int irq, void *dev_id);
  38 
  39 static unsigned int net_debug = NET_DEBUG;
  40 
  41 static const char version[] =
  42         "am79c961 ethernet driver (C) 1995-2001 Russell King v0.04\n";
  43 
  44 /* --------------------------------------------------------------------------- */
  45 
  46 #ifdef __arm__
  47 static void write_rreg(u_long base, u_int reg, u_int val)
  48 {
  49         asm volatile(
  50         "strh   %1, [%2]        @ NET_RAP\n\t"
  51         "strh   %0, [%2, #-4]   @ NET_RDP"
  52         :
  53         : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
  54 }
  55 
  56 static inline unsigned short read_rreg(u_long base_addr, u_int reg)
  57 {
  58         unsigned short v;
  59         asm volatile(
  60         "strh   %1, [%2]        @ NET_RAP\n\t"
  61         "ldrh   %0, [%2, #-4]   @ NET_RDP"
  62         : "=r" (v)
  63         : "r" (reg), "r" (ISAIO_BASE + 0x0464));
  64         return v;
  65 }
  66 
  67 static inline void write_ireg(u_long base, u_int reg, u_int val)
  68 {
  69         asm volatile(
  70         "strh   %1, [%2]        @ NET_RAP\n\t"
  71         "strh   %0, [%2, #8]    @ NET_IDP"
  72         :
  73         : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
  74 }
  75 
  76 static inline unsigned short read_ireg(u_long base_addr, u_int reg)
  77 {
  78         u_short v;
  79         asm volatile(
  80         "strh   %1, [%2]        @ NAT_RAP\n\t"
  81         "ldrh   %0, [%2, #8]    @ NET_IDP\n\t"
  82         : "=r" (v)
  83         : "r" (reg), "r" (ISAIO_BASE + 0x0464));
  84         return v;
  85 }
  86 
  87 #define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
  88 #define am_readword(dev,off)      __raw_readw(ISAMEM_BASE + ((off) << 1))
  89 
  90 static void
  91 am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
  92 {
  93         offset = ISAMEM_BASE + (offset << 1);
  94         length = (length + 1) & ~1;
  95         if ((int)buf & 2) {
  96                 asm volatile("strh      %2, [%0], #4"
  97                  : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
  98                 buf += 2;
  99                 length -= 2;
 100         }
 101         while (length > 8) {
 102                 register unsigned int tmp asm("r2"), tmp2 asm("r3");
 103                 asm volatile(
 104                         "ldmia  %0!, {%1, %2}"
 105                         : "+r" (buf), "=&r" (tmp), "=&r" (tmp2));
 106                 length -= 8;
 107                 asm volatile(
 108                         "strh   %1, [%0], #4\n\t"
 109                         "mov    %1, %1, lsr #16\n\t"
 110                         "strh   %1, [%0], #4\n\t"
 111                         "strh   %2, [%0], #4\n\t"
 112                         "mov    %2, %2, lsr #16\n\t"
 113                         "strh   %2, [%0], #4"
 114                 : "+r" (offset), "=&r" (tmp), "=&r" (tmp2));
 115         }
 116         while (length > 0) {
 117                 asm volatile("strh      %2, [%0], #4"
 118                  : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
 119                 buf += 2;
 120                 length -= 2;
 121         }
 122 }
 123 
 124 static void
 125 am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
 126 {
 127         offset = ISAMEM_BASE + (offset << 1);
 128         length = (length + 1) & ~1;
 129         if ((int)buf & 2) {
 130                 unsigned int tmp;
 131                 asm volatile(
 132                         "ldrh   %2, [%0], #4\n\t"
 133                         "strb   %2, [%1], #1\n\t"
 134                         "mov    %2, %2, lsr #8\n\t"
 135                         "strb   %2, [%1], #1"
 136                 : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
 137                 length -= 2;
 138         }
 139         while (length > 8) {
 140                 register unsigned int tmp asm("r2"), tmp2 asm("r3"), tmp3;
 141                 asm volatile(
 142                         "ldrh   %2, [%0], #4\n\t"
 143                         "ldrh   %4, [%0], #4\n\t"
 144                         "ldrh   %3, [%0], #4\n\t"
 145                         "orr    %2, %2, %4, lsl #16\n\t"
 146                         "ldrh   %4, [%0], #4\n\t"
 147                         "orr    %3, %3, %4, lsl #16\n\t"
 148                         "stmia  %1!, {%2, %3}"
 149                 : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
 150                 : "0" (offset), "1" (buf));
 151                 length -= 8;
 152         }
 153         while (length > 0) {
 154                 unsigned int tmp;
 155                 asm volatile(
 156                         "ldrh   %2, [%0], #4\n\t"
 157                         "strb   %2, [%1], #1\n\t"
 158                         "mov    %2, %2, lsr #8\n\t"
 159                         "strb   %2, [%1], #1"
 160                 : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
 161                 length -= 2;
 162         }
 163 }
 164 #else
 165 #error Not compatible
 166 #endif
 167 
 168 static int
 169 am79c961_ramtest(struct net_device *dev, unsigned int val)
 170 {
 171         unsigned char *buffer = kmalloc (65536, GFP_KERNEL);
 172         int i, error = 0, errorcount = 0;
 173 
 174         if (!buffer)
 175                 return 0;
 176         memset (buffer, val, 65536);
 177         am_writebuffer(dev, 0, buffer, 65536);
 178         memset (buffer, val ^ 255, 65536);
 179         am_readbuffer(dev, 0, buffer, 65536);
 180         for (i = 0; i < 65536; i++) {
 181                 if (buffer[i] != val && !error) {
 182                         printk ("%s: buffer error (%02X %02X) %05X - ", dev->name, val, buffer[i], i);
 183                         error = 1;
 184                         errorcount ++;
 185                 } else if (error && buffer[i] == val) {
 186                         printk ("%05X\n", i);
 187                         error = 0;
 188                 }
 189         }
 190         if (error)
 191                 printk ("10000\n");
 192         kfree (buffer);
 193         return errorcount;
 194 }
 195 
 196 static void am79c961_mc_hash(char *addr, u16 *hash)
 197 {
 198         int idx, bit;
 199         u32 crc;
 200 
 201         crc = ether_crc_le(ETH_ALEN, addr);
 202 
 203         idx = crc >> 30;
 204         bit = (crc >> 26) & 15;
 205 
 206         hash[idx] |= 1 << bit;
 207 }
 208 
 209 static unsigned int am79c961_get_rx_mode(struct net_device *dev, u16 *hash)
 210 {
 211         unsigned int mode = MODE_PORT_10BT;
 212 
 213         if (dev->flags & IFF_PROMISC) {
 214                 mode |= MODE_PROMISC;
 215                 memset(hash, 0xff, 4 * sizeof(*hash));
 216         } else if (dev->flags & IFF_ALLMULTI) {
 217                 memset(hash, 0xff, 4 * sizeof(*hash));
 218         } else {
 219                 struct netdev_hw_addr *ha;
 220 
 221                 memset(hash, 0, 4 * sizeof(*hash));
 222 
 223                 netdev_for_each_mc_addr(ha, dev)
 224                         am79c961_mc_hash(ha->addr, hash);
 225         }
 226 
 227         return mode;
 228 }
 229 
 230 static void
 231 am79c961_init_for_open(struct net_device *dev)
 232 {
 233         struct dev_priv *priv = netdev_priv(dev);
 234         unsigned long flags;
 235         unsigned char *p;
 236         u_int hdr_addr, first_free_addr;
 237         u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
 238         int i;
 239 
 240         /*
 241          * Stop the chip.
 242          */
 243         spin_lock_irqsave(&priv->chip_lock, flags);
 244         write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP);
 245         spin_unlock_irqrestore(&priv->chip_lock, flags);
 246 
 247         write_ireg (dev->base_addr, 5, 0x00a0); /* Receive address LED */
 248         write_ireg (dev->base_addr, 6, 0x0081); /* Collision LED */
 249         write_ireg (dev->base_addr, 7, 0x0090); /* XMIT LED */
 250         write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */
 251 
 252         for (i = LADRL; i <= LADRH; i++)
 253                 write_rreg (dev->base_addr, i, multi_hash[i - LADRL]);
 254 
 255         for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2)
 256                 write_rreg (dev->base_addr, i, p[0] | (p[1] << 8));
 257 
 258         write_rreg (dev->base_addr, MODE, mode);
 259         write_rreg (dev->base_addr, POLLINT, 0);
 260         write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS);
 261         write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS);
 262 
 263         first_free_addr = RX_BUFFERS * 8 + TX_BUFFERS * 8 + 16;
 264         hdr_addr = 0;
 265 
 266         priv->rxhead = 0;
 267         priv->rxtail = 0;
 268         priv->rxhdr = hdr_addr;
 269 
 270         for (i = 0; i < RX_BUFFERS; i++) {
 271                 priv->rxbuffer[i] = first_free_addr;
 272                 am_writeword (dev, hdr_addr, first_free_addr);
 273                 am_writeword (dev, hdr_addr + 2, RMD_OWN);
 274                 am_writeword (dev, hdr_addr + 4, (-1600));
 275                 am_writeword (dev, hdr_addr + 6, 0);
 276                 first_free_addr += 1600;
 277                 hdr_addr += 8;
 278         }
 279         priv->txhead = 0;
 280         priv->txtail = 0;
 281         priv->txhdr = hdr_addr;
 282         for (i = 0; i < TX_BUFFERS; i++) {
 283                 priv->txbuffer[i] = first_free_addr;
 284                 am_writeword (dev, hdr_addr, first_free_addr);
 285                 am_writeword (dev, hdr_addr + 2, TMD_STP|TMD_ENP);
 286                 am_writeword (dev, hdr_addr + 4, 0xf000);
 287                 am_writeword (dev, hdr_addr + 6, 0);
 288                 first_free_addr += 1600;
 289                 hdr_addr += 8;
 290         }
 291 
 292         write_rreg (dev->base_addr, BASERXL, priv->rxhdr);
 293         write_rreg (dev->base_addr, BASERXH, 0);
 294         write_rreg (dev->base_addr, BASETXL, priv->txhdr);
 295         write_rreg (dev->base_addr, BASERXH, 0);
 296         write_rreg (dev->base_addr, CSR0, CSR0_STOP);
 297         write_rreg (dev->base_addr, CSR3, CSR3_IDONM|CSR3_BABLM|CSR3_DXSUFLO);
 298         write_rreg (dev->base_addr, CSR4, CSR4_APAD_XMIT|CSR4_MFCOM|CSR4_RCVCCOM|CSR4_TXSTRTM|CSR4_JABM);
 299         write_rreg (dev->base_addr, CSR0, CSR0_IENA|CSR0_STRT);
 300 }
 301 
 302 static void am79c961_timer(struct timer_list *t)
 303 {
 304         struct dev_priv *priv = from_timer(priv, t, timer);
 305         struct net_device *dev = priv->dev;
 306         unsigned int lnkstat, carrier;
 307         unsigned long flags;
 308 
 309         spin_lock_irqsave(&priv->chip_lock, flags);
 310         lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
 311         spin_unlock_irqrestore(&priv->chip_lock, flags);
 312         carrier = netif_carrier_ok(dev);
 313 
 314         if (lnkstat && !carrier) {
 315                 netif_carrier_on(dev);
 316                 printk("%s: link up\n", dev->name);
 317         } else if (!lnkstat && carrier) {
 318                 netif_carrier_off(dev);
 319                 printk("%s: link down\n", dev->name);
 320         }
 321 
 322         mod_timer(&priv->timer, jiffies + msecs_to_jiffies(500));
 323 }
 324 
 325 /*
 326  * Open/initialize the board.
 327  */
 328 static int
 329 am79c961_open(struct net_device *dev)
 330 {
 331         struct dev_priv *priv = netdev_priv(dev);
 332         int ret;
 333 
 334         ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev);
 335         if (ret)
 336                 return ret;
 337 
 338         am79c961_init_for_open(dev);
 339 
 340         netif_carrier_off(dev);
 341 
 342         priv->timer.expires = jiffies;
 343         add_timer(&priv->timer);
 344 
 345         netif_start_queue(dev);
 346 
 347         return 0;
 348 }
 349 
 350 /*
 351  * The inverse routine to am79c961_open().
 352  */
 353 static int
 354 am79c961_close(struct net_device *dev)
 355 {
 356         struct dev_priv *priv = netdev_priv(dev);
 357         unsigned long flags;
 358 
 359         del_timer_sync(&priv->timer);
 360 
 361         netif_stop_queue(dev);
 362         netif_carrier_off(dev);
 363 
 364         spin_lock_irqsave(&priv->chip_lock, flags);
 365         write_rreg (dev->base_addr, CSR0, CSR0_STOP);
 366         write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
 367         spin_unlock_irqrestore(&priv->chip_lock, flags);
 368 
 369         free_irq (dev->irq, dev);
 370 
 371         return 0;
 372 }
 373 
 374 /*
 375  * Set or clear promiscuous/multicast mode filter for this adapter.
 376  */
 377 static void am79c961_setmulticastlist (struct net_device *dev)
 378 {
 379         struct dev_priv *priv = netdev_priv(dev);
 380         unsigned long flags;
 381         u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
 382         int i, stopped;
 383 
 384         spin_lock_irqsave(&priv->chip_lock, flags);
 385 
 386         stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
 387 
 388         if (!stopped) {
 389                 /*
 390                  * Put the chip into suspend mode
 391                  */
 392                 write_rreg(dev->base_addr, CTRL1, CTRL1_SPND);
 393 
 394                 /*
 395                  * Spin waiting for chip to report suspend mode
 396                  */
 397                 while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) {
 398                         spin_unlock_irqrestore(&priv->chip_lock, flags);
 399                         nop();
 400                         spin_lock_irqsave(&priv->chip_lock, flags);
 401                 }
 402         }
 403 
 404         /*
 405          * Update the multicast hash table
 406          */
 407         for (i = 0; i < ARRAY_SIZE(multi_hash); i++)
 408                 write_rreg(dev->base_addr, i + LADRL, multi_hash[i]);
 409 
 410         /*
 411          * Write the mode register
 412          */
 413         write_rreg(dev->base_addr, MODE, mode);
 414 
 415         if (!stopped) {
 416                 /*
 417                  * Put the chip back into running mode
 418                  */
 419                 write_rreg(dev->base_addr, CTRL1, 0);
 420         }
 421 
 422         spin_unlock_irqrestore(&priv->chip_lock, flags);
 423 }
 424 
 425 static void am79c961_timeout(struct net_device *dev)
 426 {
 427         printk(KERN_WARNING "%s: transmit timed out, network cable problem?\n",
 428                 dev->name);
 429 
 430         /*
 431          * ought to do some setup of the tx side here
 432          */
 433 
 434         netif_wake_queue(dev);
 435 }
 436 
 437 /*
 438  * Transmit a packet
 439  */
 440 static netdev_tx_t
 441 am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
 442 {
 443         struct dev_priv *priv = netdev_priv(dev);
 444         unsigned int hdraddr, bufaddr;
 445         unsigned int head;
 446         unsigned long flags;
 447 
 448         head = priv->txhead;
 449         hdraddr = priv->txhdr + (head << 3);
 450         bufaddr = priv->txbuffer[head];
 451         head += 1;
 452         if (head >= TX_BUFFERS)
 453                 head = 0;
 454 
 455         am_writebuffer (dev, bufaddr, skb->data, skb->len);
 456         am_writeword (dev, hdraddr + 4, -skb->len);
 457         am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
 458         priv->txhead = head;
 459 
 460         spin_lock_irqsave(&priv->chip_lock, flags);
 461         write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
 462         spin_unlock_irqrestore(&priv->chip_lock, flags);
 463 
 464         /*
 465          * If the next packet is owned by the ethernet device,
 466          * then the tx ring is full and we can't add another
 467          * packet.
 468          */
 469         if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN)
 470                 netif_stop_queue(dev);
 471 
 472         dev_consume_skb_any(skb);
 473 
 474         return NETDEV_TX_OK;
 475 }
 476 
 477 /*
 478  * If we have a good packet(s), get it/them out of the buffers.
 479  */
 480 static void
 481 am79c961_rx(struct net_device *dev, struct dev_priv *priv)
 482 {
 483         do {
 484                 struct sk_buff *skb;
 485                 u_int hdraddr;
 486                 u_int pktaddr;
 487                 u_int status;
 488                 int len;
 489 
 490                 hdraddr = priv->rxhdr + (priv->rxtail << 3);
 491                 pktaddr = priv->rxbuffer[priv->rxtail];
 492 
 493                 status = am_readword (dev, hdraddr + 2);
 494                 if (status & RMD_OWN) /* do we own it? */
 495                         break;
 496 
 497                 priv->rxtail ++;
 498                 if (priv->rxtail >= RX_BUFFERS)
 499                         priv->rxtail = 0;
 500 
 501                 if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) {
 502                         am_writeword (dev, hdraddr + 2, RMD_OWN);
 503                         dev->stats.rx_errors++;
 504                         if (status & RMD_ERR) {
 505                                 if (status & RMD_FRAM)
 506                                         dev->stats.rx_frame_errors++;
 507                                 if (status & RMD_CRC)
 508                                         dev->stats.rx_crc_errors++;
 509                         } else if (status & RMD_STP)
 510                                 dev->stats.rx_length_errors++;
 511                         continue;
 512                 }
 513 
 514                 len = am_readword(dev, hdraddr + 6);
 515                 skb = netdev_alloc_skb(dev, len + 2);
 516 
 517                 if (skb) {
 518                         skb_reserve(skb, 2);
 519 
 520                         am_readbuffer(dev, pktaddr, skb_put(skb, len), len);
 521                         am_writeword(dev, hdraddr + 2, RMD_OWN);
 522                         skb->protocol = eth_type_trans(skb, dev);
 523                         netif_rx(skb);
 524                         dev->stats.rx_bytes += len;
 525                         dev->stats.rx_packets++;
 526                 } else {
 527                         am_writeword (dev, hdraddr + 2, RMD_OWN);
 528                         dev->stats.rx_dropped++;
 529                         break;
 530                 }
 531         } while (1);
 532 }
 533 
 534 /*
 535  * Update stats for the transmitted packet
 536  */
 537 static void
 538 am79c961_tx(struct net_device *dev, struct dev_priv *priv)
 539 {
 540         do {
 541                 short len;
 542                 u_int hdraddr;
 543                 u_int status;
 544 
 545                 hdraddr = priv->txhdr + (priv->txtail << 3);
 546                 status = am_readword (dev, hdraddr + 2);
 547                 if (status & TMD_OWN)
 548                         break;
 549 
 550                 priv->txtail ++;
 551                 if (priv->txtail >= TX_BUFFERS)
 552                         priv->txtail = 0;
 553 
 554                 if (status & TMD_ERR) {
 555                         u_int status2;
 556 
 557                         dev->stats.tx_errors++;
 558 
 559                         status2 = am_readword (dev, hdraddr + 6);
 560 
 561                         /*
 562                          * Clear the error byte
 563                          */
 564                         am_writeword (dev, hdraddr + 6, 0);
 565 
 566                         if (status2 & TST_RTRY)
 567                                 dev->stats.collisions += 16;
 568                         if (status2 & TST_LCOL)
 569                                 dev->stats.tx_window_errors++;
 570                         if (status2 & TST_LCAR)
 571                                 dev->stats.tx_carrier_errors++;
 572                         if (status2 & TST_UFLO)
 573                                 dev->stats.tx_fifo_errors++;
 574                         continue;
 575                 }
 576                 dev->stats.tx_packets++;
 577                 len = am_readword (dev, hdraddr + 4);
 578                 dev->stats.tx_bytes += -len;
 579         } while (priv->txtail != priv->txhead);
 580 
 581         netif_wake_queue(dev);
 582 }
 583 
 584 static irqreturn_t
 585 am79c961_interrupt(int irq, void *dev_id)
 586 {
 587         struct net_device *dev = (struct net_device *)dev_id;
 588         struct dev_priv *priv = netdev_priv(dev);
 589         u_int status, n = 100;
 590         int handled = 0;
 591 
 592         do {
 593                 status = read_rreg(dev->base_addr, CSR0);
 594                 write_rreg(dev->base_addr, CSR0, status &
 595                            (CSR0_IENA|CSR0_TINT|CSR0_RINT|
 596                             CSR0_MERR|CSR0_MISS|CSR0_CERR|CSR0_BABL));
 597 
 598                 if (status & CSR0_RINT) {
 599                         handled = 1;
 600                         am79c961_rx(dev, priv);
 601                 }
 602                 if (status & CSR0_TINT) {
 603                         handled = 1;
 604                         am79c961_tx(dev, priv);
 605                 }
 606                 if (status & CSR0_MISS) {
 607                         handled = 1;
 608                         dev->stats.rx_dropped++;
 609                 }
 610                 if (status & CSR0_CERR) {
 611                         handled = 1;
 612                         mod_timer(&priv->timer, jiffies);
 613                 }
 614         } while (--n && status & (CSR0_RINT | CSR0_TINT));
 615 
 616         return IRQ_RETVAL(handled);
 617 }
 618 
 619 #ifdef CONFIG_NET_POLL_CONTROLLER
 620 static void am79c961_poll_controller(struct net_device *dev)
 621 {
 622         unsigned long flags;
 623         local_irq_save(flags);
 624         am79c961_interrupt(dev->irq, dev);
 625         local_irq_restore(flags);
 626 }
 627 #endif
 628 
 629 /*
 630  * Initialise the chip.  Note that we always expect
 631  * to be entered with interrupts enabled.
 632  */
 633 static int
 634 am79c961_hw_init(struct net_device *dev)
 635 {
 636         struct dev_priv *priv = netdev_priv(dev);
 637 
 638         spin_lock_irq(&priv->chip_lock);
 639         write_rreg (dev->base_addr, CSR0, CSR0_STOP);
 640         write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
 641         spin_unlock_irq(&priv->chip_lock);
 642 
 643         am79c961_ramtest(dev, 0x66);
 644         am79c961_ramtest(dev, 0x99);
 645 
 646         return 0;
 647 }
 648 
 649 static void __init am79c961_banner(void)
 650 {
 651         static unsigned version_printed;
 652 
 653         if (net_debug && version_printed++ == 0)
 654                 printk(KERN_INFO "%s", version);
 655 }
 656 static const struct net_device_ops am79c961_netdev_ops = {
 657         .ndo_open               = am79c961_open,
 658         .ndo_stop               = am79c961_close,
 659         .ndo_start_xmit         = am79c961_sendpacket,
 660         .ndo_set_rx_mode        = am79c961_setmulticastlist,
 661         .ndo_tx_timeout         = am79c961_timeout,
 662         .ndo_validate_addr      = eth_validate_addr,
 663         .ndo_set_mac_address    = eth_mac_addr,
 664 #ifdef CONFIG_NET_POLL_CONTROLLER
 665         .ndo_poll_controller    = am79c961_poll_controller,
 666 #endif
 667 };
 668 
 669 static int am79c961_probe(struct platform_device *pdev)
 670 {
 671         struct resource *res;
 672         struct net_device *dev;
 673         struct dev_priv *priv;
 674         int i, ret;
 675 
 676         res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 677         if (!res)
 678                 return -ENODEV;
 679 
 680         dev = alloc_etherdev(sizeof(struct dev_priv));
 681         ret = -ENOMEM;
 682         if (!dev)
 683                 goto out;
 684 
 685         SET_NETDEV_DEV(dev, &pdev->dev);
 686 
 687         priv = netdev_priv(dev);
 688 
 689         /*
 690          * Fixed address and IRQ lines here.
 691          * The PNP initialisation should have been
 692          * done by the ether bootp loader.
 693          */
 694         dev->base_addr = res->start;
 695         ret = platform_get_irq(pdev, 0);
 696 
 697         if (ret < 0) {
 698                 ret = -ENODEV;
 699                 goto nodev;
 700         }
 701         dev->irq = ret;
 702 
 703         ret = -ENODEV;
 704         if (!request_region(dev->base_addr, 0x18, dev->name))
 705                 goto nodev;
 706 
 707         /*
 708          * Reset the device.
 709          */
 710         inb(dev->base_addr + NET_RESET);
 711         udelay(5);
 712 
 713         /*
 714          * Check the manufacturer part of the
 715          * ether address.
 716          */
 717         if (inb(dev->base_addr) != 0x08 ||
 718             inb(dev->base_addr + 2) != 0x00 ||
 719             inb(dev->base_addr + 4) != 0x2b)
 720                 goto release;
 721 
 722         for (i = 0; i < 6; i++)
 723                 dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
 724 
 725         am79c961_banner();
 726 
 727         spin_lock_init(&priv->chip_lock);
 728         priv->dev = dev;
 729         timer_setup(&priv->timer, am79c961_timer, 0);
 730 
 731         if (am79c961_hw_init(dev))
 732                 goto release;
 733 
 734         dev->netdev_ops = &am79c961_netdev_ops;
 735 
 736         ret = register_netdev(dev);
 737         if (ret == 0) {
 738                 printk(KERN_INFO "%s: ether address %pM\n",
 739                        dev->name, dev->dev_addr);
 740                 return 0;
 741         }
 742 
 743 release:
 744         release_region(dev->base_addr, 0x18);
 745 nodev:
 746         free_netdev(dev);
 747 out:
 748         return ret;
 749 }
 750 
 751 static struct platform_driver am79c961_driver = {
 752         .probe          = am79c961_probe,
 753         .driver         = {
 754                 .name   = "am79c961",
 755         },
 756 };
 757 
 758 static int __init am79c961_init(void)
 759 {
 760         return platform_driver_register(&am79c961_driver);
 761 }
 762 
 763 __initcall(am79c961_init);

/* [<][>][^][v][top][bottom][index][help] */