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