Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.24 1034 lines 28 kB view raw
1/* 2 * de620.c $Revision: 1.40 $ BETA 3 * 4 * 5 * Linux driver for the D-Link DE-620 Ethernet pocket adapter. 6 * 7 * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall <bj0rn@blox.se> 8 * 9 * Based on adapter information gathered from DOS packetdriver 10 * sources from D-Link Inc: (Special thanks to Henry Ngai of D-Link.) 11 * Portions (C) Copyright D-Link SYSTEM Inc. 1991, 1992 12 * Copyright, 1988, Russell Nelson, Crynwr Software 13 * 14 * Adapted to the sample network driver core for linux, 15 * written by: Donald Becker <becker@super.org> 16 * (Now at <becker@scyld.com>) 17 * 18 * Valuable assistance from: 19 * J. Joshua Kopper <kopper@rtsg.mot.com> 20 * Olav Kvittem <Olav.Kvittem@uninett.no> 21 * Germano Caronni <caronni@nessie.cs.id.ethz.ch> 22 * Jeremy Fitzhardinge <jeremy@suite.sw.oz.au> 23 * 24 *****************************************************************************/ 25/* 26 * This program is free software; you can redistribute it and/or modify 27 * it under the terms of the GNU General Public License as published by 28 * the Free Software Foundation; either version 2, or (at your option) 29 * any later version. 30 * 31 * This program is distributed in the hope that it will be useful, 32 * but WITHOUT ANY WARRANTY; without even the implied warranty of 33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 * GNU General Public License for more details. 35 * 36 * You should have received a copy of the GNU General Public License 37 * along with this program; if not, write to the Free Software 38 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 39 * 40 *****************************************************************************/ 41static const char version[] = 42 "de620.c: $Revision: 1.40 $, Bjorn Ekwall <bj0rn@blox.se>\n"; 43 44/*********************************************************************** 45 * 46 * "Tuning" section. 47 * 48 * Compile-time options: (see below for descriptions) 49 * -DDE620_IO=0x378 (lpt1) 50 * -DDE620_IRQ=7 (lpt1) 51 * -DDE602_DEBUG=... 52 * -DSHUTDOWN_WHEN_LOST 53 * -DCOUNT_LOOPS 54 * -DLOWSPEED 55 * -DREAD_DELAY 56 * -DWRITE_DELAY 57 */ 58 59/* 60 * This driver assumes that the printer port is a "normal", 61 * dumb, uni-directional port! 62 * If your port is "fancy" in any way, please try to set it to "normal" 63 * with your BIOS setup. I have no access to machines with bi-directional 64 * ports, so I can't test such a driver :-( 65 * (Yes, I _know_ it is possible to use DE620 with bidirectional ports...) 66 * 67 * There are some clones of DE620 out there, with different names. 68 * If the current driver does not recognize a clone, try to change 69 * the following #define to: 70 * 71 * #define DE620_CLONE 1 72 */ 73#define DE620_CLONE 0 74 75/* 76 * If the adapter has problems with high speeds, enable this #define 77 * otherwise full printerport speed will be attempted. 78 * 79 * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED 80 * 81#define LOWSPEED 82 */ 83 84#ifndef READ_DELAY 85#define READ_DELAY 100 /* adapter internal read delay in 100ns units */ 86#endif 87 88#ifndef WRITE_DELAY 89#define WRITE_DELAY 100 /* adapter internal write delay in 100ns units */ 90#endif 91 92/* 93 * Enable this #define if you want the adapter to do a "ifconfig down" on 94 * itself when we have detected that something is possibly wrong with it. 95 * The default behaviour is to retry with "adapter_init()" until success. 96 * This should be used for debugging purposes only. 97 * 98#define SHUTDOWN_WHEN_LOST 99 */ 100 101/* 102 * Enable debugging by "-DDE620_DEBUG=3" when compiling, 103 * OR by enabling the following #define 104 * 105 * use 0 for production, 1 for verification, >2 for debug 106 * 107#define DE620_DEBUG 3 108 */ 109 110#ifdef LOWSPEED 111/* 112 * Enable this #define if you want to see debugging output that show how long 113 * we have to wait before the DE-620 is ready for the next read/write/command. 114 * 115#define COUNT_LOOPS 116 */ 117#endif 118 119#include <linux/module.h> 120#include <linux/kernel.h> 121#include <linux/types.h> 122#include <linux/fcntl.h> 123#include <linux/string.h> 124#include <linux/interrupt.h> 125#include <linux/ioport.h> 126#include <linux/in.h> 127#include <linux/errno.h> 128#include <linux/init.h> 129#include <linux/inet.h> 130#include <linux/netdevice.h> 131#include <linux/etherdevice.h> 132#include <linux/skbuff.h> 133 134#include <asm/io.h> 135#include <asm/system.h> 136 137/* Constant definitions for the DE-620 registers, commands and bits */ 138#include "de620.h" 139 140typedef unsigned char byte; 141 142/******************************************************* 143 * * 144 * Definition of D-Link DE-620 Ethernet Pocket adapter * 145 * See also "de620.h" * 146 * * 147 *******************************************************/ 148#ifndef DE620_IO /* Compile-time configurable */ 149#define DE620_IO 0x378 150#endif 151 152#ifndef DE620_IRQ /* Compile-time configurable */ 153#define DE620_IRQ 7 154#endif 155 156#define DATA_PORT (dev->base_addr) 157#define STATUS_PORT (dev->base_addr + 1) 158#define COMMAND_PORT (dev->base_addr + 2) 159 160#define RUNT 60 /* Too small Ethernet packet */ 161#define GIANT 1514 /* largest legal size packet, no fcs */ 162 163#ifdef DE620_DEBUG /* Compile-time configurable */ 164#define PRINTK(x) if (de620_debug >= 2) printk x 165#else 166#define DE620_DEBUG 0 167#define PRINTK(x) /**/ 168#endif 169 170 171/* 172 * Force media with insmod: 173 * insmod de620.o bnc=1 174 * or 175 * insmod de620.o utp=1 176 * 177 * Force io and/or irq with insmod: 178 * insmod de620.o io=0x378 irq=7 179 * 180 * Make a clone skip the Ethernet-address range check: 181 * insmod de620.o clone=1 182 */ 183static int bnc; 184static int utp; 185static int io = DE620_IO; 186static int irq = DE620_IRQ; 187static int clone = DE620_CLONE; 188 189static unsigned int de620_debug = DE620_DEBUG; 190 191static spinlock_t de620_lock; 192 193module_param(bnc, int, 0); 194module_param(utp, int, 0); 195module_param(io, int, 0); 196module_param(irq, int, 0); 197module_param(clone, int, 0); 198module_param(de620_debug, int, 0); 199MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)"); 200MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)"); 201MODULE_PARM_DESC(io, "DE-620 I/O base address,required"); 202MODULE_PARM_DESC(irq, "DE-620 IRQ number,required"); 203MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)"); 204MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)"); 205 206/*********************************************** 207 * * 208 * Index to functions, as function prototypes. * 209 * * 210 ***********************************************/ 211 212/* 213 * Routines used internally. (See also "convenience macros.. below") 214 */ 215 216/* Put in the device structure. */ 217static int de620_open(struct net_device *); 218static int de620_close(struct net_device *); 219static void de620_set_multicast_list(struct net_device *); 220static int de620_start_xmit(struct sk_buff *, struct net_device *); 221 222/* Dispatch from interrupts. */ 223static irqreturn_t de620_interrupt(int, void *); 224static int de620_rx_intr(struct net_device *); 225 226/* Initialization */ 227static int adapter_init(struct net_device *); 228static int read_eeprom(struct net_device *); 229 230 231/* 232 * D-Link driver variables: 233 */ 234#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX 235#define TCR_DEF RXPB /* not used: | TXSUCINT | T16INT */ 236#define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */ 237#define DEF_NIC_CMD IRQEN | ICEN | DS1 238 239static volatile byte NIC_Cmd; 240static volatile byte next_rx_page; 241static byte first_rx_page; 242static byte last_rx_page; 243static byte EIPRegister; 244 245static struct nic { 246 byte NodeID[6]; 247 byte RAM_Size; 248 byte Model; 249 byte Media; 250 byte SCR; 251} nic_data; 252 253/********************************************************** 254 * * 255 * Convenience macros/functions for D-Link DE-620 adapter * 256 * * 257 **********************************************************/ 258#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1)) 259#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT); 260 261/* Check for ready-status, and return a nibble (high 4 bits) for data input */ 262#ifdef COUNT_LOOPS 263static int tot_cnt; 264#endif 265static inline byte 266de620_ready(struct net_device *dev) 267{ 268 byte value; 269 register short int cnt = 0; 270 271 while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000)) 272 ++cnt; 273 274#ifdef COUNT_LOOPS 275 tot_cnt += cnt; 276#endif 277 return value & 0xf0; /* nibble */ 278} 279 280static inline void 281de620_send_command(struct net_device *dev, byte cmd) 282{ 283 de620_ready(dev); 284 if (cmd == W_DUMMY) 285 outb(NIC_Cmd, COMMAND_PORT); 286 287 outb(cmd, DATA_PORT); 288 289 outb(NIC_Cmd ^ CS0, COMMAND_PORT); 290 de620_ready(dev); 291 outb(NIC_Cmd, COMMAND_PORT); 292} 293 294static inline void 295de620_put_byte(struct net_device *dev, byte value) 296{ 297 /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */ 298 de620_ready(dev); 299 outb(value, DATA_PORT); 300 de620_flip_ds(dev); 301} 302 303static inline byte 304de620_read_byte(struct net_device *dev) 305{ 306 byte value; 307 308 /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */ 309 value = de620_ready(dev); /* High nibble */ 310 de620_flip_ds(dev); 311 value |= de620_ready(dev) >> 4; /* Low nibble */ 312 return value; 313} 314 315static inline void 316de620_write_block(struct net_device *dev, byte *buffer, int count, int pad) 317{ 318#ifndef LOWSPEED 319 byte uflip = NIC_Cmd ^ (DS0 | DS1); 320 byte dflip = NIC_Cmd; 321#else /* LOWSPEED */ 322#ifdef COUNT_LOOPS 323 int bytes = count; 324#endif /* COUNT_LOOPS */ 325#endif /* LOWSPEED */ 326 327#ifdef LOWSPEED 328#ifdef COUNT_LOOPS 329 tot_cnt = 0; 330#endif /* COUNT_LOOPS */ 331 /* No further optimization useful, the limit is in the adapter. */ 332 for ( ; count > 0; --count, ++buffer) { 333 de620_put_byte(dev,*buffer); 334 } 335 for ( count = pad ; count > 0; --count, ++buffer) { 336 de620_put_byte(dev, 0); 337 } 338 de620_send_command(dev,W_DUMMY); 339#ifdef COUNT_LOOPS 340 /* trial debug output: loops per byte in de620_ready() */ 341 printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1))); 342#endif /* COUNT_LOOPS */ 343#else /* not LOWSPEED */ 344 for ( ; count > 0; count -=2) { 345 outb(*buffer++, DATA_PORT); 346 outb(uflip, COMMAND_PORT); 347 outb(*buffer++, DATA_PORT); 348 outb(dflip, COMMAND_PORT); 349 } 350 de620_send_command(dev,W_DUMMY); 351#endif /* LOWSPEED */ 352} 353 354static inline void 355de620_read_block(struct net_device *dev, byte *data, int count) 356{ 357#ifndef LOWSPEED 358 byte value; 359 byte uflip = NIC_Cmd ^ (DS0 | DS1); 360 byte dflip = NIC_Cmd; 361#else /* LOWSPEED */ 362#ifdef COUNT_LOOPS 363 int bytes = count; 364 365 tot_cnt = 0; 366#endif /* COUNT_LOOPS */ 367#endif /* LOWSPEED */ 368 369#ifdef LOWSPEED 370 /* No further optimization useful, the limit is in the adapter. */ 371 while (count-- > 0) { 372 *data++ = de620_read_byte(dev); 373 de620_flip_ds(dev); 374 } 375#ifdef COUNT_LOOPS 376 /* trial debug output: loops per byte in de620_ready() */ 377 printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1))); 378#endif /* COUNT_LOOPS */ 379#else /* not LOWSPEED */ 380 while (count-- > 0) { 381 value = inb(STATUS_PORT) & 0xf0; /* High nibble */ 382 outb(uflip, COMMAND_PORT); 383 *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */ 384 outb(dflip , COMMAND_PORT); 385 } 386#endif /* LOWSPEED */ 387} 388 389static inline void 390de620_set_delay(struct net_device *dev) 391{ 392 de620_ready(dev); 393 outb(W_DFR, DATA_PORT); 394 outb(NIC_Cmd ^ CS0, COMMAND_PORT); 395 396 de620_ready(dev); 397#ifdef LOWSPEED 398 outb(WRITE_DELAY, DATA_PORT); 399#else 400 outb(0, DATA_PORT); 401#endif 402 de620_flip_ds(dev); 403 404 de620_ready(dev); 405#ifdef LOWSPEED 406 outb(READ_DELAY, DATA_PORT); 407#else 408 outb(0, DATA_PORT); 409#endif 410 de620_flip_ds(dev); 411} 412 413static inline void 414de620_set_register(struct net_device *dev, byte reg, byte value) 415{ 416 de620_ready(dev); 417 outb(reg, DATA_PORT); 418 outb(NIC_Cmd ^ CS0, COMMAND_PORT); 419 420 de620_put_byte(dev, value); 421} 422 423static inline byte 424de620_get_register(struct net_device *dev, byte reg) 425{ 426 byte value; 427 428 de620_send_command(dev,reg); 429 value = de620_read_byte(dev); 430 de620_send_command(dev,W_DUMMY); 431 432 return value; 433} 434 435/********************************************************************* 436 * 437 * Open/initialize the board. 438 * 439 * This routine should set everything up anew at each open, even 440 * registers that "should" only need to be set once at boot, so that 441 * there is a non-reboot way to recover if something goes wrong. 442 * 443 */ 444static int de620_open(struct net_device *dev) 445{ 446 int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev); 447 if (ret) { 448 printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq); 449 return ret; 450 } 451 452 if (adapter_init(dev)) { 453 ret = -EIO; 454 goto out_free_irq; 455 } 456 457 netif_start_queue(dev); 458 return 0; 459 460out_free_irq: 461 free_irq(dev->irq, dev); 462 return ret; 463} 464 465/************************************************ 466 * 467 * The inverse routine to de620_open(). 468 * 469 */ 470 471static int de620_close(struct net_device *dev) 472{ 473 netif_stop_queue(dev); 474 /* disable recv */ 475 de620_set_register(dev, W_TCR, RXOFF); 476 free_irq(dev->irq, dev); 477 return 0; 478} 479 480/********************************************* 481 * 482 * Set or clear the multicast filter for this adaptor. 483 * (no real multicast implemented for the DE-620, but she can be promiscuous...) 484 * 485 */ 486 487static void de620_set_multicast_list(struct net_device *dev) 488{ 489 if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 490 { /* Enable promiscuous mode */ 491 /* 492 * We must make the kernel realise we had to move 493 * into promisc mode or we start all out war on 494 * the cable. - AC 495 */ 496 dev->flags|=IFF_PROMISC; 497 498 de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL); 499 } 500 else 501 { /* Disable promiscuous mode, use normal mode */ 502 de620_set_register(dev, W_TCR, TCR_DEF); 503 } 504} 505 506/******************************************************* 507 * 508 * Handle timeouts on transmit 509 */ 510 511static void de620_timeout(struct net_device *dev) 512{ 513 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, "network cable problem"); 514 /* Restart the adapter. */ 515 if (!adapter_init(dev)) /* maybe close it */ 516 netif_wake_queue(dev); 517} 518 519/******************************************************* 520 * 521 * Copy a buffer to the adapter transmit page memory. 522 * Start sending. 523 */ 524static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev) 525{ 526 unsigned long flags; 527 int len; 528 byte *buffer = skb->data; 529 byte using_txbuf; 530 531 using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */ 532 533 netif_stop_queue(dev); 534 535 536 if ((len = skb->len) < RUNT) 537 len = RUNT; 538 if (len & 1) /* send an even number of bytes */ 539 ++len; 540 541 /* Start real output */ 542 543 spin_lock_irqsave(&de620_lock, flags) 544 PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n", 545 (int)skb->len, using_txbuf)); 546 547 /* select a free tx buffer. if there is one... */ 548 switch (using_txbuf) { 549 default: /* both are free: use TXBF0 */ 550 case TXBF1: /* use TXBF0 */ 551 de620_send_command(dev,W_CR | RW0); 552 using_txbuf |= TXBF0; 553 break; 554 555 case TXBF0: /* use TXBF1 */ 556 de620_send_command(dev,W_CR | RW1); 557 using_txbuf |= TXBF1; 558 break; 559 560 case (TXBF0 | TXBF1): /* NONE!!! */ 561 printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name); 562 spin_unlock_irqrestore(&de620_lock, flags); 563 return 1; 564 } 565 de620_write_block(dev, buffer, skb->len, len-skb->len); 566 567 dev->trans_start = jiffies; 568 if(!(using_txbuf == (TXBF0 | TXBF1))) 569 netif_wake_queue(dev); 570 571 dev->stats.tx_packets++; 572 spin_unlock_irqrestore(&de620_lock, flags); 573 dev_kfree_skb (skb); 574 return 0; 575} 576 577/***************************************************** 578 * 579 * Handle the network interface interrupts. 580 * 581 */ 582static irqreturn_t 583de620_interrupt(int irq_in, void *dev_id) 584{ 585 struct net_device *dev = dev_id; 586 byte irq_status; 587 int bogus_count = 0; 588 int again = 0; 589 590 spin_lock(&de620_lock); 591 592 /* Read the status register (_not_ the status port) */ 593 irq_status = de620_get_register(dev, R_STS); 594 595 PRINTK(("de620_interrupt (%2.2X)\n", irq_status)); 596 597 if (irq_status & RXGOOD) { 598 do { 599 again = de620_rx_intr(dev); 600 PRINTK(("again=%d\n", again)); 601 } 602 while (again && (++bogus_count < 100)); 603 } 604 605 if(de620_tx_buffs(dev) != (TXBF0 | TXBF1)) 606 netif_wake_queue(dev); 607 608 spin_unlock(&de620_lock); 609 return IRQ_HANDLED; 610} 611 612/************************************** 613 * 614 * Get a packet from the adapter 615 * 616 * Send it "upstairs" 617 * 618 */ 619static int de620_rx_intr(struct net_device *dev) 620{ 621 struct header_buf { 622 byte status; 623 byte Rx_NextPage; 624 unsigned short Rx_ByteCount; 625 } header_buf; 626 struct sk_buff *skb; 627 int size; 628 byte *buffer; 629 byte pagelink; 630 byte curr_page; 631 632 PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page)); 633 634 /* Tell the adapter that we are going to read data, and from where */ 635 de620_send_command(dev, W_CR | RRN); 636 de620_set_register(dev, W_RSA1, next_rx_page); 637 de620_set_register(dev, W_RSA0, 0); 638 639 /* Deep breath, and away we goooooo */ 640 de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf)); 641 PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n", 642 header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount)); 643 644 /* Plausible page header? */ 645 pagelink = header_buf.Rx_NextPage; 646 if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) { 647 /* Ouch... Forget it! Skip all and start afresh... */ 648 printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name); 649 /* You win some, you lose some. And sometimes plenty... */ 650 adapter_init(dev); 651 netif_wake_queue(dev); 652 dev->stats.rx_over_errors++; 653 return 0; 654 } 655 656 /* OK, this look good, so far. Let's see if it's consistent... */ 657 /* Let's compute the start of the next packet, based on where we are */ 658 pagelink = next_rx_page + 659 ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8); 660 661 /* Are we going to wrap around the page counter? */ 662 if (pagelink > last_rx_page) 663 pagelink -= (last_rx_page - first_rx_page + 1); 664 665 /* Is the _computed_ next page number equal to what the adapter says? */ 666 if (pagelink != header_buf.Rx_NextPage) { 667 /* Naah, we'll skip this packet. Probably bogus data as well */ 668 printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name); 669 next_rx_page = header_buf.Rx_NextPage; /* at least a try... */ 670 de620_send_command(dev, W_DUMMY); 671 de620_set_register(dev, W_NPRF, next_rx_page); 672 dev->stats.rx_over_errors++; 673 return 0; 674 } 675 next_rx_page = pagelink; 676 677 size = header_buf.Rx_ByteCount - 4; 678 if ((size < RUNT) || (GIANT < size)) { 679 printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size); 680 } 681 else { /* Good packet? */ 682 skb = dev_alloc_skb(size+2); 683 if (skb == NULL) { /* Yeah, but no place to put it... */ 684 printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size); 685 dev->stats.rx_dropped++; 686 } 687 else { /* Yep! Go get it! */ 688 skb_reserve(skb,2); /* Align */ 689 /* skb->data points to the start of sk_buff data area */ 690 buffer = skb_put(skb,size); 691 /* copy the packet into the buffer */ 692 de620_read_block(dev, buffer, size); 693 PRINTK(("Read %d bytes\n", size)); 694 skb->protocol=eth_type_trans(skb,dev); 695 netif_rx(skb); /* deliver it "upstairs" */ 696 dev->last_rx = jiffies; 697 /* count all receives */ 698 dev->stats.rx_packets++; 699 dev->stats.rx_bytes += size; 700 } 701 } 702 703 /* Let's peek ahead to see if we have read the last current packet */ 704 /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */ 705 curr_page = de620_get_register(dev, R_CPR); 706 de620_set_register(dev, W_NPRF, next_rx_page); 707 PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page)); 708 709 return (next_rx_page != curr_page); /* That was slightly tricky... */ 710} 711 712/********************************************* 713 * 714 * Reset the adapter to a known state 715 * 716 */ 717static int adapter_init(struct net_device *dev) 718{ 719 int i; 720 static int was_down; 721 722 if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */ 723 EIPRegister = NCTL0; 724 if (nic_data.Media != 1) 725 EIPRegister |= NIS0; /* not BNC */ 726 } 727 else if (nic_data.Model == 2) { /* UTP */ 728 EIPRegister = NCTL0 | NIS0; 729 } 730 731 if (utp) 732 EIPRegister = NCTL0 | NIS0; 733 if (bnc) 734 EIPRegister = NCTL0; 735 736 de620_send_command(dev, W_CR | RNOP | CLEAR); 737 de620_send_command(dev, W_CR | RNOP); 738 739 de620_set_register(dev, W_SCR, SCR_DEF); 740 /* disable recv to wait init */ 741 de620_set_register(dev, W_TCR, RXOFF); 742 743 /* Set the node ID in the adapter */ 744 for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */ 745 de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]); 746 } 747 748 de620_set_register(dev, W_EIP, EIPRegister); 749 750 next_rx_page = first_rx_page = DE620_RX_START_PAGE; 751 if (nic_data.RAM_Size) 752 last_rx_page = nic_data.RAM_Size - 1; 753 else /* 64k RAM */ 754 last_rx_page = 255; 755 756 de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/ 757 de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */ 758 de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/ 759 de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/ 760 de620_send_command(dev, W_DUMMY); 761 de620_set_delay(dev); 762 763 /* Final sanity check: Anybody out there? */ 764 /* Let's hope some bits from the statusregister make a good check */ 765#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 ) 766#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ) 767 /* success: X 0 0 X 0 0 X X */ 768 /* ignore: EEDI RXGOOD COLS LNKS*/ 769 770 if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) { 771 printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it" 772#ifdef SHUTDOWN_WHEN_LOST 773 " and do a new ifconfig" 774#endif 775 "! (%02x)\n", dev->name, i); 776#ifdef SHUTDOWN_WHEN_LOST 777 /* Goodbye, cruel world... */ 778 dev->flags &= ~IFF_UP; 779 de620_close(dev); 780#endif 781 was_down = 1; 782 return 1; /* failed */ 783 } 784 if (was_down) { 785 printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name); 786 was_down = 0; 787 } 788 789 /* All OK, go ahead... */ 790 de620_set_register(dev, W_TCR, TCR_DEF); 791 792 return 0; /* all ok */ 793} 794 795/****************************************************************************** 796 * 797 * Only start-up code below 798 * 799 */ 800/**************************************** 801 * 802 * Check if there is a DE-620 connected 803 */ 804struct net_device * __init de620_probe(int unit) 805{ 806 byte checkbyte = 0xa5; 807 struct net_device *dev; 808 int err = -ENOMEM; 809 int i; 810 DECLARE_MAC_BUF(mac); 811 812 dev = alloc_etherdev(0); 813 if (!dev) 814 goto out; 815 816 spin_lock_init(&de620_lock); 817 818 /* 819 * This is where the base_addr and irq gets set. 820 * Tunable at compile-time and insmod-time 821 */ 822 dev->base_addr = io; 823 dev->irq = irq; 824 825 /* allow overriding parameters on command line */ 826 if (unit >= 0) { 827 sprintf(dev->name, "eth%d", unit); 828 netdev_boot_setup_check(dev); 829 } 830 831 if (de620_debug) 832 printk(version); 833 834 printk(KERN_INFO "D-Link DE-620 pocket adapter"); 835 836 if (!request_region(dev->base_addr, 3, "de620")) { 837 printk(" io 0x%3lX, which is busy.\n", dev->base_addr); 838 err = -EBUSY; 839 goto out1; 840 } 841 842 /* Initially, configure basic nibble mode, so we can read the EEPROM */ 843 NIC_Cmd = DEF_NIC_CMD; 844 de620_set_register(dev, W_EIP, EIPRegister); 845 846 /* Anybody out there? */ 847 de620_set_register(dev, W_CPR, checkbyte); 848 checkbyte = de620_get_register(dev, R_CPR); 849 850 if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) { 851 printk(" not identified in the printer port\n"); 852 err = -ENODEV; 853 goto out2; 854 } 855 856 /* else, got it! */ 857 dev->dev_addr[0] = nic_data.NodeID[0]; 858 for (i = 1; i < ETH_ALEN; i++) { 859 dev->dev_addr[i] = nic_data.NodeID[i]; 860 dev->broadcast[i] = 0xff; 861 } 862 863 printk(", Ethernet Address: %s", print_mac(mac, dev->dev_addr)); 864 865 printk(" (%dk RAM,", 866 (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64); 867 868 if (nic_data.Media == 1) 869 printk(" BNC)\n"); 870 else 871 printk(" UTP)\n"); 872 873 dev->open = de620_open; 874 dev->stop = de620_close; 875 dev->hard_start_xmit = de620_start_xmit; 876 dev->tx_timeout = de620_timeout; 877 dev->watchdog_timeo = HZ*2; 878 dev->set_multicast_list = de620_set_multicast_list; 879 880 /* base_addr and irq are already set, see above! */ 881 882 /* dump eeprom */ 883 if (de620_debug) { 884 printk("\nEEPROM contents:\n"); 885 printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size); 886 printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n", 887 nic_data.NodeID[0], nic_data.NodeID[1], 888 nic_data.NodeID[2], nic_data.NodeID[3], 889 nic_data.NodeID[4], nic_data.NodeID[5]); 890 printk("Model = %d\n", nic_data.Model); 891 printk("Media = %d\n", nic_data.Media); 892 printk("SCR = 0x%02x\n", nic_data.SCR); 893 } 894 895 err = register_netdev(dev); 896 if (err) 897 goto out2; 898 return dev; 899 900out2: 901 release_region(dev->base_addr, 3); 902out1: 903 free_netdev(dev); 904out: 905 return ERR_PTR(err); 906} 907 908/********************************** 909 * 910 * Read info from on-board EEPROM 911 * 912 * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_! 913 */ 914#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister); 915 916static unsigned short __init ReadAWord(struct net_device *dev, int from) 917{ 918 unsigned short data; 919 int nbits; 920 921 /* cs [__~~] SET SEND STATE */ 922 /* di [____] */ 923 /* sck [_~~_] */ 924 sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4); 925 926 /* Send the 9-bit address from where we want to read the 16-bit word */ 927 for (nbits = 9; nbits > 0; --nbits, from <<= 1) { 928 if (from & 0x0100) { /* bit set? */ 929 /* cs [~~~~] SEND 1 */ 930 /* di [~~~~] */ 931 /* sck [_~~_] */ 932 sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6); 933 } 934 else { 935 /* cs [~~~~] SEND 0 */ 936 /* di [____] */ 937 /* sck [_~~_] */ 938 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4); 939 } 940 } 941 942 /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */ 943 for (data = 0, nbits = 16; nbits > 0; --nbits) { 944 /* cs [~~~~] SEND 0 */ 945 /* di [____] */ 946 /* sck [_~~_] */ 947 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4); 948 data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7); 949 } 950 /* cs [____] RESET SEND STATE */ 951 /* di [____] */ 952 /* sck [_~~_] */ 953 sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0); 954 955 return data; 956} 957 958static int __init read_eeprom(struct net_device *dev) 959{ 960 unsigned short wrd; 961 962 /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */ 963 wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */ 964 if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */ 965 return -1; /* Nope, not a DE-620 */ 966 nic_data.NodeID[0] = wrd & 0xff; 967 nic_data.NodeID[1] = wrd >> 8; 968 969 wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */ 970 if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */ 971 return -1; /* Nope, not a DE-620 */ 972 nic_data.NodeID[2] = wrd & 0xff; 973 nic_data.NodeID[3] = wrd >> 8; 974 975 wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */ 976 nic_data.NodeID[4] = wrd & 0xff; 977 nic_data.NodeID[5] = wrd >> 8; 978 979 wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */ 980 nic_data.RAM_Size = (wrd >> 8); 981 982 wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */ 983 nic_data.Model = (wrd & 0xff); 984 985 wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */ 986 nic_data.Media = (wrd & 0xff); 987 988 wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */ 989 nic_data.SCR = (wrd >> 8); 990 991 return 0; /* no errors */ 992} 993 994/****************************************************************************** 995 * 996 * Loadable module skeleton 997 * 998 */ 999#ifdef MODULE 1000static struct net_device *de620_dev; 1001 1002int __init init_module(void) 1003{ 1004 de620_dev = de620_probe(-1); 1005 if (IS_ERR(de620_dev)) 1006 return PTR_ERR(de620_dev); 1007 return 0; 1008} 1009 1010void cleanup_module(void) 1011{ 1012 unregister_netdev(de620_dev); 1013 release_region(de620_dev->base_addr, 3); 1014 free_netdev(de620_dev); 1015} 1016#endif /* MODULE */ 1017MODULE_LICENSE("GPL"); 1018 1019 1020/* 1021 * (add '-DMODULE' when compiling as loadable module) 1022 * 1023 * compile-command: 1024 * gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \ 1025 * -fomit-frame-pointer -m486 \ 1026 * -I/usr/src/linux/include -I../../net/inet -c de620.c 1027*/ 1028/* 1029 * Local variables: 1030 * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1031 * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1032 * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1033 * End: 1034 */