1/* 2 * de620.c $Revision: 1.1.1.1 $ 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.1.1.1 $, 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 121#include <linux/kernel.h> 122#include <linux/sched.h> 123#include <linux/types.h> 124#include <linux/fcntl.h> 125#include <linux/string.h> 126#include <linux/interrupt.h> 127#include <linux/ioport.h> 128#include <asm/io.h> 129#include <linux/in.h> 130#include <linux/ptrace.h> 131#include <asm/system.h> 132#include <linux/errno.h> 133#include <linux/init.h> 134 135#include <linux/inet.h> 136#include <linux/netdevice.h> 137#include <linux/etherdevice.h> 138#include <linux/skbuff.h> 139 140/* Constant definitions for the DE-620 registers, commands and bits */ 141#include "de620.h" 142 143typedef unsigned char byte; 144 145/******************************************************* 146 * * 147 * Definition of D-Link DE-620 Ethernet Pocket adapter * 148 * See also "de620.h" * 149 * * 150 *******************************************************/ 151#ifndef DE620_IO /* Compile-time configurable */ 152#define DE620_IO 0x378 153#endif 154 155#ifndef DE620_IRQ /* Compile-time configurable */ 156#define DE620_IRQ 7 157#endif 158 159#define DATA_PORT (dev->base_addr) 160#define STATUS_PORT (dev->base_addr + 1) 161#define COMMAND_PORT (dev->base_addr + 2) 162 163#define RUNT 60 /* Too small Ethernet packet */ 164#define GIANT 1514 /* largest legal size packet, no fcs */ 165 166#ifdef DE620_DEBUG /* Compile-time configurable */ 167#define PRINTK(x) if (de620_debug >= 2) printk x 168#else 169#define DE620_DEBUG 0 170#define PRINTK(x) /**/ 171#endif 172 173 174/* 175 * Force media with insmod: 176 * insmod de620.o bnc=1 177 * or 178 * insmod de620.o utp=1 179 * 180 * Force io and/or irq with insmod: 181 * insmod de620.o io=0x378 irq=7 182 * 183 * Make a clone skip the Ethernet-address range check: 184 * insmod de620.o clone=1 185 */ 186static int bnc; 187static int utp; 188static int io = DE620_IO; 189static int irq = DE620_IRQ; 190static int clone = DE620_CLONE; 191 192static unsigned int de620_debug = DE620_DEBUG; 193 194MODULE_PARM(bnc, "i"); 195MODULE_PARM(utp, "i"); 196MODULE_PARM(io, "i"); 197MODULE_PARM(irq, "i"); 198MODULE_PARM(clone, "i"); 199MODULE_PARM(de620_debug, "i"); 200MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)"); 201MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)"); 202MODULE_PARM_DESC(io, "DE-620 I/O base address,required"); 203MODULE_PARM_DESC(irq, "DE-620 IRQ number,required"); 204MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)"); 205MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)"); 206 207/*********************************************** 208 * * 209 * Index to functions, as function prototypes. * 210 * * 211 ***********************************************/ 212 213/* 214 * Routines used internally. (See also "convenience macros.. below") 215 */ 216 217/* Put in the device structure. */ 218static int de620_open(struct net_device *); 219static int de620_close(struct net_device *); 220static struct net_device_stats *get_stats(struct net_device *); 221static void de620_set_multicast_list(struct net_device *); 222static int de620_start_xmit(struct sk_buff *, struct net_device *); 223 224/* Dispatch from interrupts. */ 225static void de620_interrupt(int, void *, struct pt_regs *); 226static int de620_rx_intr(struct net_device *); 227 228/* Initialization */ 229static int adapter_init(struct net_device *); 230int de620_probe(struct net_device *); 231static int read_eeprom(struct net_device *); 232 233 234/* 235 * D-Link driver variables: 236 */ 237#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX 238#define TCR_DEF RXPB /* not used: | TXSUCINT | T16INT */ 239#define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */ 240#define DEF_NIC_CMD IRQEN | ICEN | DS1 241 242static volatile byte NIC_Cmd; 243static volatile byte next_rx_page; 244static byte first_rx_page; 245static byte last_rx_page; 246static byte EIPRegister; 247 248static struct nic { 249 byte NodeID[6]; 250 byte RAM_Size; 251 byte Model; 252 byte Media; 253 byte SCR; 254} nic_data; 255 256/********************************************************** 257 * * 258 * Convenience macros/functions for D-Link DE-620 adapter * 259 * * 260 **********************************************************/ 261#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1)) 262#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT); 263 264/* Check for ready-status, and return a nibble (high 4 bits) for data input */ 265#ifdef COUNT_LOOPS 266static int tot_cnt; 267#endif 268static inline byte 269de620_ready(struct net_device *dev) 270{ 271 byte value; 272 register short int cnt = 0; 273 274 while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000)) 275 ++cnt; 276 277#ifdef COUNT_LOOPS 278 tot_cnt += cnt; 279#endif 280 return value & 0xf0; /* nibble */ 281} 282 283static inline void 284de620_send_command(struct net_device *dev, byte cmd) 285{ 286 de620_ready(dev); 287 if (cmd == W_DUMMY) 288 outb(NIC_Cmd, COMMAND_PORT); 289 290 outb(cmd, DATA_PORT); 291 292 outb(NIC_Cmd ^ CS0, COMMAND_PORT); 293 de620_ready(dev); 294 outb(NIC_Cmd, COMMAND_PORT); 295} 296 297static inline void 298de620_put_byte(struct net_device *dev, byte value) 299{ 300 /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */ 301 de620_ready(dev); 302 outb(value, DATA_PORT); 303 de620_flip_ds(dev); 304} 305 306static inline byte 307de620_read_byte(struct net_device *dev) 308{ 309 byte value; 310 311 /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */ 312 value = de620_ready(dev); /* High nibble */ 313 de620_flip_ds(dev); 314 value |= de620_ready(dev) >> 4; /* Low nibble */ 315 return value; 316} 317 318static inline void 319de620_write_block(struct net_device *dev, byte *buffer, int count) 320{ 321#ifndef LOWSPEED 322 byte uflip = NIC_Cmd ^ (DS0 | DS1); 323 byte dflip = NIC_Cmd; 324#else /* LOWSPEED */ 325#ifdef COUNT_LOOPS 326 int bytes = count; 327#endif /* COUNT_LOOPS */ 328#endif /* LOWSPEED */ 329 330#ifdef LOWSPEED 331#ifdef COUNT_LOOPS 332 tot_cnt = 0; 333#endif /* COUNT_LOOPS */ 334 /* No further optimization useful, the limit is in the adapter. */ 335 for ( ; count > 0; --count, ++buffer) { 336 de620_put_byte(dev,*buffer); 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 * Return current statistics 483 * 484 */ 485static struct net_device_stats *get_stats(struct net_device *dev) 486{ 487 return (struct net_device_stats *)(dev->priv); 488} 489 490/********************************************* 491 * 492 * Set or clear the multicast filter for this adaptor. 493 * (no real multicast implemented for the DE-620, but she can be promiscuous...) 494 * 495 */ 496 497static void de620_set_multicast_list(struct net_device *dev) 498{ 499 if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 500 { /* Enable promiscuous mode */ 501 /* 502 * We must make the kernel realise we had to move 503 * into promisc mode or we start all out war on 504 * the cable. - AC 505 */ 506 dev->flags|=IFF_PROMISC; 507 508 de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL); 509 } 510 else 511 { /* Disable promiscuous mode, use normal mode */ 512 de620_set_register(dev, W_TCR, TCR_DEF); 513 } 514} 515 516/******************************************************* 517 * 518 * Handle timeouts on transmit 519 */ 520 521static void de620_timeout(struct net_device *dev) 522{ 523 printk("%s: transmit timed out, %s?\n", 524 dev->name, 525 "network cable problem" 526 ); 527 /* Restart the adapter. */ 528 if (!adapter_init(dev)) /* maybe close it */ 529 netif_wake_queue(dev); 530} 531 532/******************************************************* 533 * 534 * Copy a buffer to the adapter transmit page memory. 535 * Start sending. 536 */ 537static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev) 538{ 539 unsigned long flags; 540 int len; 541 byte *buffer = skb->data; 542 byte using_txbuf; 543 544 using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */ 545 546 netif_stop_queue(dev); 547 548 549 if ((len = skb->len) < RUNT) 550 len = RUNT; 551 if (len & 1) /* send an even number of bytes */ 552 ++len; 553 554 /* Start real output */ 555 save_flags(flags); 556 cli(); 557 558 PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n", 559 (int)skb->len, using_txbuf)); 560 561 /* select a free tx buffer. if there is one... */ 562 switch (using_txbuf) { 563 default: /* both are free: use TXBF0 */ 564 case TXBF1: /* use TXBF0 */ 565 de620_send_command(dev,W_CR | RW0); 566 using_txbuf |= TXBF0; 567 break; 568 569 case TXBF0: /* use TXBF1 */ 570 de620_send_command(dev,W_CR | RW1); 571 using_txbuf |= TXBF1; 572 break; 573 574 case (TXBF0 | TXBF1): /* NONE!!! */ 575 printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name); 576 restore_flags(flags); 577 return 1; 578 } 579 de620_write_block(dev, buffer, len); 580 581 dev->trans_start = jiffies; 582 if(!(using_txbuf == (TXBF0 | TXBF1))) 583 netif_wake_queue(dev); 584 585 ((struct net_device_stats *)(dev->priv))->tx_packets++; 586 restore_flags(flags); /* interrupts maybe back on */ 587 dev_kfree_skb (skb); 588 return 0; 589} 590 591/***************************************************** 592 * 593 * Handle the network interface interrupts. 594 * 595 */ 596static void de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs) 597{ 598 struct net_device *dev = dev_id; 599 byte irq_status; 600 int bogus_count = 0; 601 int again = 0; 602 603 /* This might be deleted now, no crummy drivers present :-) Or..? */ 604 if ((dev == NULL) || (irq != irq_in)) { 605 printk("%s: bogus interrupt %d\n", dev?dev->name:"de620", irq_in); 606 return; 607 } 608 609 /* Read the status register (_not_ the status port) */ 610 irq_status = de620_get_register(dev, R_STS); 611 612 PRINTK(("de620_interrupt (%2.2X)\n", irq_status)); 613 614 if (irq_status & RXGOOD) { 615 do { 616 again = de620_rx_intr(dev); 617 PRINTK(("again=%d\n", again)); 618 } 619 while (again && (++bogus_count < 100)); 620 } 621 622 if(de620_tx_buffs(dev) != (TXBF0 | TXBF1)) 623 netif_wake_queue(dev); 624} 625 626/************************************** 627 * 628 * Get a packet from the adapter 629 * 630 * Send it "upstairs" 631 * 632 */ 633static int de620_rx_intr(struct net_device *dev) 634{ 635 struct header_buf { 636 byte status; 637 byte Rx_NextPage; 638 unsigned short Rx_ByteCount; 639 } header_buf; 640 struct sk_buff *skb; 641 int size; 642 byte *buffer; 643 byte pagelink; 644 byte curr_page; 645 646 PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page)); 647 648 /* Tell the adapter that we are going to read data, and from where */ 649 de620_send_command(dev, W_CR | RRN); 650 de620_set_register(dev, W_RSA1, next_rx_page); 651 de620_set_register(dev, W_RSA0, 0); 652 653 /* Deep breath, and away we goooooo */ 654 de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf)); 655 PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n", 656 header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount)); 657 658 /* Plausible page header? */ 659 pagelink = header_buf.Rx_NextPage; 660 if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) { 661 /* Ouch... Forget it! Skip all and start afresh... */ 662 printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name); 663 /* You win some, you lose some. And sometimes plenty... */ 664 adapter_init(dev); 665 netif_wake_queue(dev); 666 ((struct net_device_stats *)(dev->priv))->rx_over_errors++; 667 return 0; 668 } 669 670 /* OK, this look good, so far. Let's see if it's consistent... */ 671 /* Let's compute the start of the next packet, based on where we are */ 672 pagelink = next_rx_page + 673 ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8); 674 675 /* Are we going to wrap around the page counter? */ 676 if (pagelink > last_rx_page) 677 pagelink -= (last_rx_page - first_rx_page + 1); 678 679 /* Is the _computed_ next page number equal to what the adapter says? */ 680 if (pagelink != header_buf.Rx_NextPage) { 681 /* Naah, we'll skip this packet. Probably bogus data as well */ 682 printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name); 683 next_rx_page = header_buf.Rx_NextPage; /* at least a try... */ 684 de620_send_command(dev, W_DUMMY); 685 de620_set_register(dev, W_NPRF, next_rx_page); 686 ((struct net_device_stats *)(dev->priv))->rx_over_errors++; 687 return 0; 688 } 689 next_rx_page = pagelink; 690 691 size = header_buf.Rx_ByteCount - 4; 692 if ((size < RUNT) || (GIANT < size)) { 693 printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size); 694 } 695 else { /* Good packet? */ 696 skb = dev_alloc_skb(size+2); 697 if (skb == NULL) { /* Yeah, but no place to put it... */ 698 printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", 699 dev->name, size); 700 ((struct net_device_stats *)(dev->priv))->rx_dropped++; 701 } 702 else { /* Yep! Go get it! */ 703 skb_reserve(skb,2); /* Align */ 704 skb->dev = dev; 705 /* skb->data points to the start of sk_buff data area */ 706 buffer = skb_put(skb,size); 707 /* copy the packet into the buffer */ 708 de620_read_block(dev, buffer, size); 709 PRINTK(("Read %d bytes\n", size)); 710 skb->protocol=eth_type_trans(skb,dev); 711 netif_rx(skb); /* deliver it "upstairs" */ 712 dev->last_rx = jiffies; 713 /* count all receives */ 714 ((struct net_device_stats *)(dev->priv))->rx_packets++; 715 ((struct net_device_stats *)(dev->priv))->rx_bytes += size; 716 } 717 } 718 719 /* Let's peek ahead to see if we have read the last current packet */ 720 /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */ 721 curr_page = de620_get_register(dev, R_CPR); 722 de620_set_register(dev, W_NPRF, next_rx_page); 723 PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page)); 724 725 return (next_rx_page != curr_page); /* That was slightly tricky... */ 726} 727 728/********************************************* 729 * 730 * Reset the adapter to a known state 731 * 732 */ 733static int adapter_init(struct net_device *dev) 734{ 735 int i; 736 static int was_down; 737 738 if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */ 739 EIPRegister = NCTL0; 740 if (nic_data.Media != 1) 741 EIPRegister |= NIS0; /* not BNC */ 742 } 743 else if (nic_data.Model == 2) { /* UTP */ 744 EIPRegister = NCTL0 | NIS0; 745 } 746 747 if (utp) 748 EIPRegister = NCTL0 | NIS0; 749 if (bnc) 750 EIPRegister = NCTL0; 751 752 de620_send_command(dev, W_CR | RNOP | CLEAR); 753 de620_send_command(dev, W_CR | RNOP); 754 755 de620_set_register(dev, W_SCR, SCR_DEF); 756 /* disable recv to wait init */ 757 de620_set_register(dev, W_TCR, RXOFF); 758 759 /* Set the node ID in the adapter */ 760 for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */ 761 de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]); 762 } 763 764 de620_set_register(dev, W_EIP, EIPRegister); 765 766 next_rx_page = first_rx_page = DE620_RX_START_PAGE; 767 if (nic_data.RAM_Size) 768 last_rx_page = nic_data.RAM_Size - 1; 769 else /* 64k RAM */ 770 last_rx_page = 255; 771 772 de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/ 773 de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */ 774 de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/ 775 de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/ 776 de620_send_command(dev, W_DUMMY); 777 de620_set_delay(dev); 778 779 /* Final sanity check: Anybody out there? */ 780 /* Let's hope some bits from the statusregister make a good check */ 781#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 ) 782#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ) 783 /* success: X 0 0 X 0 0 X X */ 784 /* ignore: EEDI RXGOOD COLS LNKS*/ 785 786 if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) { 787 printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it" 788#ifdef SHUTDOWN_WHEN_LOST 789 " and do a new ifconfig" 790#endif 791 "! (%02x)\n", dev->name, i); 792#ifdef SHUTDOWN_WHEN_LOST 793 /* Goodbye, cruel world... */ 794 dev->flags &= ~IFF_UP; 795 de620_close(dev); 796#endif 797 was_down = 1; 798 return 1; /* failed */ 799 } 800 if (was_down) { 801 printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name); 802 was_down = 0; 803 } 804 805 /* All OK, go ahead... */ 806 de620_set_register(dev, W_TCR, TCR_DEF); 807 808 return 0; /* all ok */ 809} 810 811/****************************************************************************** 812 * 813 * Only start-up code below 814 * 815 */ 816/**************************************** 817 * 818 * Check if there is a DE-620 connected 819 */ 820int __init de620_probe(struct net_device *dev) 821{ 822 static struct net_device_stats de620_netstats; 823 int i; 824 byte checkbyte = 0xa5; 825 826 SET_MODULE_OWNER(dev); 827 828 /* 829 * This is where the base_addr and irq gets set. 830 * Tunable at compile-time and insmod-time 831 */ 832 dev->base_addr = io; 833 dev->irq = irq; 834 835 if (de620_debug) 836 printk(version); 837 838 printk(KERN_INFO "D-Link DE-620 pocket adapter"); 839 840 /* Initially, configure basic nibble mode, so we can read the EEPROM */ 841 NIC_Cmd = DEF_NIC_CMD; 842 de620_set_register(dev, W_EIP, EIPRegister); 843 844 /* Anybody out there? */ 845 de620_set_register(dev, W_CPR, checkbyte); 846 checkbyte = de620_get_register(dev, R_CPR); 847 848 if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) { 849 printk(" not identified in the printer port\n"); 850 return -ENODEV; 851 } 852 853 if (!request_region(dev->base_addr, 3, "de620")) { 854 printk(KERN_ERR "io 0x%3lX, which is busy.\n", dev->base_addr); 855 return -EBUSY; 856 } 857 858 /* else, got it! */ 859 printk(", Ethernet Address: %2.2X", 860 dev->dev_addr[0] = nic_data.NodeID[0]); 861 for (i = 1; i < ETH_ALEN; i++) { 862 printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]); 863 dev->broadcast[i] = 0xff; 864 } 865 866 printk(" (%dk RAM,", 867 (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64); 868 869 if (nic_data.Media == 1) 870 printk(" BNC)\n"); 871 else 872 printk(" UTP)\n"); 873 874 /* Initialize the device structure. */ 875 dev->priv = &de620_netstats; 876 877 memset(dev->priv, 0, sizeof(struct net_device_stats)); 878 dev->get_stats = get_stats; 879 dev->open = de620_open; 880 dev->stop = de620_close; 881 dev->hard_start_xmit = de620_start_xmit; 882 dev->tx_timeout = de620_timeout; 883 dev->watchdog_timeo = HZ*2; 884 dev->set_multicast_list = de620_set_multicast_list; 885 886 /* base_addr and irq are already set, see above! */ 887 888 ether_setup(dev); 889 890 /* dump eeprom */ 891 if (de620_debug) { 892 printk("\nEEPROM contents:\n"); 893 printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size); 894 printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n", 895 nic_data.NodeID[0], nic_data.NodeID[1], 896 nic_data.NodeID[2], nic_data.NodeID[3], 897 nic_data.NodeID[4], nic_data.NodeID[5]); 898 printk("Model = %d\n", nic_data.Model); 899 printk("Media = %d\n", nic_data.Media); 900 printk("SCR = 0x%02x\n", nic_data.SCR); 901 } 902 903 return 0; 904} 905 906/********************************** 907 * 908 * Read info from on-board EEPROM 909 * 910 * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_! 911 */ 912#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister); 913 914static unsigned short __init ReadAWord(struct net_device *dev, int from) 915{ 916 unsigned short data; 917 int nbits; 918 919 /* cs [__~~] SET SEND STATE */ 920 /* di [____] */ 921 /* sck [_~~_] */ 922 sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4); 923 924 /* Send the 9-bit address from where we want to read the 16-bit word */ 925 for (nbits = 9; nbits > 0; --nbits, from <<= 1) { 926 if (from & 0x0100) { /* bit set? */ 927 /* cs [~~~~] SEND 1 */ 928 /* di [~~~~] */ 929 /* sck [_~~_] */ 930 sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6); 931 } 932 else { 933 /* cs [~~~~] SEND 0 */ 934 /* di [____] */ 935 /* sck [_~~_] */ 936 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4); 937 } 938 } 939 940 /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */ 941 for (data = 0, nbits = 16; nbits > 0; --nbits) { 942 /* cs [~~~~] SEND 0 */ 943 /* di [____] */ 944 /* sck [_~~_] */ 945 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4); 946 data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7); 947 } 948 /* cs [____] RESET SEND STATE */ 949 /* di [____] */ 950 /* sck [_~~_] */ 951 sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0); 952 953 return data; 954} 955 956static int __init read_eeprom(struct net_device *dev) 957{ 958 unsigned short wrd; 959 960 /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */ 961 wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */ 962 if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */ 963 return -1; /* Nope, not a DE-620 */ 964 nic_data.NodeID[0] = wrd & 0xff; 965 nic_data.NodeID[1] = wrd >> 8; 966 967 wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */ 968 if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */ 969 return -1; /* Nope, not a DE-620 */ 970 nic_data.NodeID[2] = wrd & 0xff; 971 nic_data.NodeID[3] = wrd >> 8; 972 973 wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */ 974 nic_data.NodeID[4] = wrd & 0xff; 975 nic_data.NodeID[5] = wrd >> 8; 976 977 wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */ 978 nic_data.RAM_Size = (wrd >> 8); 979 980 wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */ 981 nic_data.Model = (wrd & 0xff); 982 983 wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */ 984 nic_data.Media = (wrd & 0xff); 985 986 wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */ 987 nic_data.SCR = (wrd >> 8); 988 989 return 0; /* no errors */ 990} 991 992/****************************************************************************** 993 * 994 * Loadable module skeleton 995 * 996 */ 997#ifdef MODULE 998static struct net_device de620_dev; 999 1000int init_module(void) 1001{ 1002 de620_dev.init = de620_probe; 1003 if (register_netdev(&de620_dev) != 0) 1004 return -EIO; 1005 return 0; 1006} 1007 1008void cleanup_module(void) 1009{ 1010 unregister_netdev(&de620_dev); 1011 release_region(de620_dev.base_addr, 3); 1012} 1013#endif /* MODULE */ 1014MODULE_LICENSE("GPL"); 1015 1016 1017/* 1018 * (add '-DMODULE' when compiling as loadable module) 1019 * 1020 * compile-command: 1021 * gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \ 1022 * -fomit-frame-pointer -m486 \ 1023 * -I/usr/src/linux/include -I../../net/inet -c de620.c 1024*/ 1025/* 1026 * Local variables: 1027 * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1028 * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1029 * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1030 * End: 1031 */ 1032