at v2.6.14 1047 lines 29 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 struct net_device_stats *get_stats(struct net_device *); 220static void de620_set_multicast_list(struct net_device *); 221static int de620_start_xmit(struct sk_buff *, struct net_device *); 222 223/* Dispatch from interrupts. */ 224static irqreturn_t de620_interrupt(int, void *, struct pt_regs *); 225static int de620_rx_intr(struct net_device *); 226 227/* Initialization */ 228static int adapter_init(struct net_device *); 229static int read_eeprom(struct net_device *); 230 231 232/* 233 * D-Link driver variables: 234 */ 235#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX 236#define TCR_DEF RXPB /* not used: | TXSUCINT | T16INT */ 237#define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */ 238#define DEF_NIC_CMD IRQEN | ICEN | DS1 239 240static volatile byte NIC_Cmd; 241static volatile byte next_rx_page; 242static byte first_rx_page; 243static byte last_rx_page; 244static byte EIPRegister; 245 246static struct nic { 247 byte NodeID[6]; 248 byte RAM_Size; 249 byte Model; 250 byte Media; 251 byte SCR; 252} nic_data; 253 254/********************************************************** 255 * * 256 * Convenience macros/functions for D-Link DE-620 adapter * 257 * * 258 **********************************************************/ 259#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1)) 260#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT); 261 262/* Check for ready-status, and return a nibble (high 4 bits) for data input */ 263#ifdef COUNT_LOOPS 264static int tot_cnt; 265#endif 266static inline byte 267de620_ready(struct net_device *dev) 268{ 269 byte value; 270 register short int cnt = 0; 271 272 while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000)) 273 ++cnt; 274 275#ifdef COUNT_LOOPS 276 tot_cnt += cnt; 277#endif 278 return value & 0xf0; /* nibble */ 279} 280 281static inline void 282de620_send_command(struct net_device *dev, byte cmd) 283{ 284 de620_ready(dev); 285 if (cmd == W_DUMMY) 286 outb(NIC_Cmd, COMMAND_PORT); 287 288 outb(cmd, DATA_PORT); 289 290 outb(NIC_Cmd ^ CS0, COMMAND_PORT); 291 de620_ready(dev); 292 outb(NIC_Cmd, COMMAND_PORT); 293} 294 295static inline void 296de620_put_byte(struct net_device *dev, byte value) 297{ 298 /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */ 299 de620_ready(dev); 300 outb(value, DATA_PORT); 301 de620_flip_ds(dev); 302} 303 304static inline byte 305de620_read_byte(struct net_device *dev) 306{ 307 byte value; 308 309 /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */ 310 value = de620_ready(dev); /* High nibble */ 311 de620_flip_ds(dev); 312 value |= de620_ready(dev) >> 4; /* Low nibble */ 313 return value; 314} 315 316static inline void 317de620_write_block(struct net_device *dev, byte *buffer, int count, int pad) 318{ 319#ifndef LOWSPEED 320 byte uflip = NIC_Cmd ^ (DS0 | DS1); 321 byte dflip = NIC_Cmd; 322#else /* LOWSPEED */ 323#ifdef COUNT_LOOPS 324 int bytes = count; 325#endif /* COUNT_LOOPS */ 326#endif /* LOWSPEED */ 327 328#ifdef LOWSPEED 329#ifdef COUNT_LOOPS 330 tot_cnt = 0; 331#endif /* COUNT_LOOPS */ 332 /* No further optimization useful, the limit is in the adapter. */ 333 for ( ; count > 0; --count, ++buffer) { 334 de620_put_byte(dev,*buffer); 335 } 336 for ( count = pad ; count > 0; --count, ++buffer) { 337 de620_put_byte(dev, 0); 338 } 339 de620_send_command(dev,W_DUMMY); 340#ifdef COUNT_LOOPS 341 /* trial debug output: loops per byte in de620_ready() */ 342 printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1))); 343#endif /* COUNT_LOOPS */ 344#else /* not LOWSPEED */ 345 for ( ; count > 0; count -=2) { 346 outb(*buffer++, DATA_PORT); 347 outb(uflip, COMMAND_PORT); 348 outb(*buffer++, DATA_PORT); 349 outb(dflip, COMMAND_PORT); 350 } 351 de620_send_command(dev,W_DUMMY); 352#endif /* LOWSPEED */ 353} 354 355static inline void 356de620_read_block(struct net_device *dev, byte *data, int count) 357{ 358#ifndef LOWSPEED 359 byte value; 360 byte uflip = NIC_Cmd ^ (DS0 | DS1); 361 byte dflip = NIC_Cmd; 362#else /* LOWSPEED */ 363#ifdef COUNT_LOOPS 364 int bytes = count; 365 366 tot_cnt = 0; 367#endif /* COUNT_LOOPS */ 368#endif /* LOWSPEED */ 369 370#ifdef LOWSPEED 371 /* No further optimization useful, the limit is in the adapter. */ 372 while (count-- > 0) { 373 *data++ = de620_read_byte(dev); 374 de620_flip_ds(dev); 375 } 376#ifdef COUNT_LOOPS 377 /* trial debug output: loops per byte in de620_ready() */ 378 printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1))); 379#endif /* COUNT_LOOPS */ 380#else /* not LOWSPEED */ 381 while (count-- > 0) { 382 value = inb(STATUS_PORT) & 0xf0; /* High nibble */ 383 outb(uflip, COMMAND_PORT); 384 *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */ 385 outb(dflip , COMMAND_PORT); 386 } 387#endif /* LOWSPEED */ 388} 389 390static inline void 391de620_set_delay(struct net_device *dev) 392{ 393 de620_ready(dev); 394 outb(W_DFR, DATA_PORT); 395 outb(NIC_Cmd ^ CS0, COMMAND_PORT); 396 397 de620_ready(dev); 398#ifdef LOWSPEED 399 outb(WRITE_DELAY, DATA_PORT); 400#else 401 outb(0, DATA_PORT); 402#endif 403 de620_flip_ds(dev); 404 405 de620_ready(dev); 406#ifdef LOWSPEED 407 outb(READ_DELAY, DATA_PORT); 408#else 409 outb(0, DATA_PORT); 410#endif 411 de620_flip_ds(dev); 412} 413 414static inline void 415de620_set_register(struct net_device *dev, byte reg, byte value) 416{ 417 de620_ready(dev); 418 outb(reg, DATA_PORT); 419 outb(NIC_Cmd ^ CS0, COMMAND_PORT); 420 421 de620_put_byte(dev, value); 422} 423 424static inline byte 425de620_get_register(struct net_device *dev, byte reg) 426{ 427 byte value; 428 429 de620_send_command(dev,reg); 430 value = de620_read_byte(dev); 431 de620_send_command(dev,W_DUMMY); 432 433 return value; 434} 435 436/********************************************************************* 437 * 438 * Open/initialize the board. 439 * 440 * This routine should set everything up anew at each open, even 441 * registers that "should" only need to be set once at boot, so that 442 * there is a non-reboot way to recover if something goes wrong. 443 * 444 */ 445static int de620_open(struct net_device *dev) 446{ 447 int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev); 448 if (ret) { 449 printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq); 450 return ret; 451 } 452 453 if (adapter_init(dev)) { 454 ret = -EIO; 455 goto out_free_irq; 456 } 457 458 netif_start_queue(dev); 459 return 0; 460 461out_free_irq: 462 free_irq(dev->irq, dev); 463 return ret; 464} 465 466/************************************************ 467 * 468 * The inverse routine to de620_open(). 469 * 470 */ 471 472static int de620_close(struct net_device *dev) 473{ 474 netif_stop_queue(dev); 475 /* disable recv */ 476 de620_set_register(dev, W_TCR, RXOFF); 477 free_irq(dev->irq, dev); 478 return 0; 479} 480 481/********************************************* 482 * 483 * Return current statistics 484 * 485 */ 486static struct net_device_stats *get_stats(struct net_device *dev) 487{ 488 return (struct net_device_stats *)(dev->priv); 489} 490 491/********************************************* 492 * 493 * Set or clear the multicast filter for this adaptor. 494 * (no real multicast implemented for the DE-620, but she can be promiscuous...) 495 * 496 */ 497 498static void de620_set_multicast_list(struct net_device *dev) 499{ 500 if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 501 { /* Enable promiscuous mode */ 502 /* 503 * We must make the kernel realise we had to move 504 * into promisc mode or we start all out war on 505 * the cable. - AC 506 */ 507 dev->flags|=IFF_PROMISC; 508 509 de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL); 510 } 511 else 512 { /* Disable promiscuous mode, use normal mode */ 513 de620_set_register(dev, W_TCR, TCR_DEF); 514 } 515} 516 517/******************************************************* 518 * 519 * Handle timeouts on transmit 520 */ 521 522static void de620_timeout(struct net_device *dev) 523{ 524 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, "network cable problem"); 525 /* Restart the adapter. */ 526 if (!adapter_init(dev)) /* maybe close it */ 527 netif_wake_queue(dev); 528} 529 530/******************************************************* 531 * 532 * Copy a buffer to the adapter transmit page memory. 533 * Start sending. 534 */ 535static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev) 536{ 537 unsigned long flags; 538 int len; 539 byte *buffer = skb->data; 540 byte using_txbuf; 541 542 using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */ 543 544 netif_stop_queue(dev); 545 546 547 if ((len = skb->len) < RUNT) 548 len = RUNT; 549 if (len & 1) /* send an even number of bytes */ 550 ++len; 551 552 /* Start real output */ 553 554 spin_lock_irqsave(&de620_lock, flags) 555 PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n", 556 (int)skb->len, using_txbuf)); 557 558 /* select a free tx buffer. if there is one... */ 559 switch (using_txbuf) { 560 default: /* both are free: use TXBF0 */ 561 case TXBF1: /* use TXBF0 */ 562 de620_send_command(dev,W_CR | RW0); 563 using_txbuf |= TXBF0; 564 break; 565 566 case TXBF0: /* use TXBF1 */ 567 de620_send_command(dev,W_CR | RW1); 568 using_txbuf |= TXBF1; 569 break; 570 571 case (TXBF0 | TXBF1): /* NONE!!! */ 572 printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name); 573 spin_unlock_irqrestore(&de620_lock, flags); 574 return 1; 575 } 576 de620_write_block(dev, buffer, skb->len, len-skb->len); 577 578 dev->trans_start = jiffies; 579 if(!(using_txbuf == (TXBF0 | TXBF1))) 580 netif_wake_queue(dev); 581 582 ((struct net_device_stats *)(dev->priv))->tx_packets++; 583 spin_unlock_irqrestore(&de620_lock, flags); 584 dev_kfree_skb (skb); 585 return 0; 586} 587 588/***************************************************** 589 * 590 * Handle the network interface interrupts. 591 * 592 */ 593static irqreturn_t 594de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs) 595{ 596 struct net_device *dev = dev_id; 597 byte irq_status; 598 int bogus_count = 0; 599 int again = 0; 600 601 spin_lock(&de620_lock); 602 603 /* Read the status register (_not_ the status port) */ 604 irq_status = de620_get_register(dev, R_STS); 605 606 PRINTK(("de620_interrupt (%2.2X)\n", irq_status)); 607 608 if (irq_status & RXGOOD) { 609 do { 610 again = de620_rx_intr(dev); 611 PRINTK(("again=%d\n", again)); 612 } 613 while (again && (++bogus_count < 100)); 614 } 615 616 if(de620_tx_buffs(dev) != (TXBF0 | TXBF1)) 617 netif_wake_queue(dev); 618 619 spin_unlock(&de620_lock); 620 return IRQ_HANDLED; 621} 622 623/************************************** 624 * 625 * Get a packet from the adapter 626 * 627 * Send it "upstairs" 628 * 629 */ 630static int de620_rx_intr(struct net_device *dev) 631{ 632 struct header_buf { 633 byte status; 634 byte Rx_NextPage; 635 unsigned short Rx_ByteCount; 636 } header_buf; 637 struct sk_buff *skb; 638 int size; 639 byte *buffer; 640 byte pagelink; 641 byte curr_page; 642 643 PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page)); 644 645 /* Tell the adapter that we are going to read data, and from where */ 646 de620_send_command(dev, W_CR | RRN); 647 de620_set_register(dev, W_RSA1, next_rx_page); 648 de620_set_register(dev, W_RSA0, 0); 649 650 /* Deep breath, and away we goooooo */ 651 de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf)); 652 PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n", 653 header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount)); 654 655 /* Plausible page header? */ 656 pagelink = header_buf.Rx_NextPage; 657 if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) { 658 /* Ouch... Forget it! Skip all and start afresh... */ 659 printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name); 660 /* You win some, you lose some. And sometimes plenty... */ 661 adapter_init(dev); 662 netif_wake_queue(dev); 663 ((struct net_device_stats *)(dev->priv))->rx_over_errors++; 664 return 0; 665 } 666 667 /* OK, this look good, so far. Let's see if it's consistent... */ 668 /* Let's compute the start of the next packet, based on where we are */ 669 pagelink = next_rx_page + 670 ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8); 671 672 /* Are we going to wrap around the page counter? */ 673 if (pagelink > last_rx_page) 674 pagelink -= (last_rx_page - first_rx_page + 1); 675 676 /* Is the _computed_ next page number equal to what the adapter says? */ 677 if (pagelink != header_buf.Rx_NextPage) { 678 /* Naah, we'll skip this packet. Probably bogus data as well */ 679 printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name); 680 next_rx_page = header_buf.Rx_NextPage; /* at least a try... */ 681 de620_send_command(dev, W_DUMMY); 682 de620_set_register(dev, W_NPRF, next_rx_page); 683 ((struct net_device_stats *)(dev->priv))->rx_over_errors++; 684 return 0; 685 } 686 next_rx_page = pagelink; 687 688 size = header_buf.Rx_ByteCount - 4; 689 if ((size < RUNT) || (GIANT < size)) { 690 printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size); 691 } 692 else { /* Good packet? */ 693 skb = dev_alloc_skb(size+2); 694 if (skb == NULL) { /* Yeah, but no place to put it... */ 695 printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size); 696 ((struct net_device_stats *)(dev->priv))->rx_dropped++; 697 } 698 else { /* Yep! Go get it! */ 699 skb_reserve(skb,2); /* Align */ 700 skb->dev = dev; 701 /* skb->data points to the start of sk_buff data area */ 702 buffer = skb_put(skb,size); 703 /* copy the packet into the buffer */ 704 de620_read_block(dev, buffer, size); 705 PRINTK(("Read %d bytes\n", size)); 706 skb->protocol=eth_type_trans(skb,dev); 707 netif_rx(skb); /* deliver it "upstairs" */ 708 dev->last_rx = jiffies; 709 /* count all receives */ 710 ((struct net_device_stats *)(dev->priv))->rx_packets++; 711 ((struct net_device_stats *)(dev->priv))->rx_bytes += size; 712 } 713 } 714 715 /* Let's peek ahead to see if we have read the last current packet */ 716 /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */ 717 curr_page = de620_get_register(dev, R_CPR); 718 de620_set_register(dev, W_NPRF, next_rx_page); 719 PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page)); 720 721 return (next_rx_page != curr_page); /* That was slightly tricky... */ 722} 723 724/********************************************* 725 * 726 * Reset the adapter to a known state 727 * 728 */ 729static int adapter_init(struct net_device *dev) 730{ 731 int i; 732 static int was_down; 733 734 if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */ 735 EIPRegister = NCTL0; 736 if (nic_data.Media != 1) 737 EIPRegister |= NIS0; /* not BNC */ 738 } 739 else if (nic_data.Model == 2) { /* UTP */ 740 EIPRegister = NCTL0 | NIS0; 741 } 742 743 if (utp) 744 EIPRegister = NCTL0 | NIS0; 745 if (bnc) 746 EIPRegister = NCTL0; 747 748 de620_send_command(dev, W_CR | RNOP | CLEAR); 749 de620_send_command(dev, W_CR | RNOP); 750 751 de620_set_register(dev, W_SCR, SCR_DEF); 752 /* disable recv to wait init */ 753 de620_set_register(dev, W_TCR, RXOFF); 754 755 /* Set the node ID in the adapter */ 756 for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */ 757 de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]); 758 } 759 760 de620_set_register(dev, W_EIP, EIPRegister); 761 762 next_rx_page = first_rx_page = DE620_RX_START_PAGE; 763 if (nic_data.RAM_Size) 764 last_rx_page = nic_data.RAM_Size - 1; 765 else /* 64k RAM */ 766 last_rx_page = 255; 767 768 de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/ 769 de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */ 770 de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/ 771 de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/ 772 de620_send_command(dev, W_DUMMY); 773 de620_set_delay(dev); 774 775 /* Final sanity check: Anybody out there? */ 776 /* Let's hope some bits from the statusregister make a good check */ 777#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 ) 778#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ) 779 /* success: X 0 0 X 0 0 X X */ 780 /* ignore: EEDI RXGOOD COLS LNKS*/ 781 782 if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) { 783 printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it" 784#ifdef SHUTDOWN_WHEN_LOST 785 " and do a new ifconfig" 786#endif 787 "! (%02x)\n", dev->name, i); 788#ifdef SHUTDOWN_WHEN_LOST 789 /* Goodbye, cruel world... */ 790 dev->flags &= ~IFF_UP; 791 de620_close(dev); 792#endif 793 was_down = 1; 794 return 1; /* failed */ 795 } 796 if (was_down) { 797 printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name); 798 was_down = 0; 799 } 800 801 /* All OK, go ahead... */ 802 de620_set_register(dev, W_TCR, TCR_DEF); 803 804 return 0; /* all ok */ 805} 806 807/****************************************************************************** 808 * 809 * Only start-up code below 810 * 811 */ 812/**************************************** 813 * 814 * Check if there is a DE-620 connected 815 */ 816struct net_device * __init de620_probe(int unit) 817{ 818 byte checkbyte = 0xa5; 819 struct net_device *dev; 820 int err = -ENOMEM; 821 int i; 822 823 dev = alloc_etherdev(sizeof(struct net_device_stats)); 824 if (!dev) 825 goto out; 826 827 SET_MODULE_OWNER(dev); 828 829 spin_lock_init(&de620_lock); 830 831 /* 832 * This is where the base_addr and irq gets set. 833 * Tunable at compile-time and insmod-time 834 */ 835 dev->base_addr = io; 836 dev->irq = irq; 837 838 /* allow overriding parameters on command line */ 839 if (unit >= 0) { 840 sprintf(dev->name, "eth%d", unit); 841 netdev_boot_setup_check(dev); 842 } 843 844 if (de620_debug) 845 printk(version); 846 847 printk(KERN_INFO "D-Link DE-620 pocket adapter"); 848 849 if (!request_region(dev->base_addr, 3, "de620")) { 850 printk(" io 0x%3lX, which is busy.\n", dev->base_addr); 851 err = -EBUSY; 852 goto out1; 853 } 854 855 /* Initially, configure basic nibble mode, so we can read the EEPROM */ 856 NIC_Cmd = DEF_NIC_CMD; 857 de620_set_register(dev, W_EIP, EIPRegister); 858 859 /* Anybody out there? */ 860 de620_set_register(dev, W_CPR, checkbyte); 861 checkbyte = de620_get_register(dev, R_CPR); 862 863 if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) { 864 printk(" not identified in the printer port\n"); 865 err = -ENODEV; 866 goto out2; 867 } 868 869 /* else, got it! */ 870 printk(", Ethernet Address: %2.2X", 871 dev->dev_addr[0] = nic_data.NodeID[0]); 872 for (i = 1; i < ETH_ALEN; i++) { 873 printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]); 874 dev->broadcast[i] = 0xff; 875 } 876 877 printk(" (%dk RAM,", 878 (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64); 879 880 if (nic_data.Media == 1) 881 printk(" BNC)\n"); 882 else 883 printk(" UTP)\n"); 884 885 dev->get_stats = get_stats; 886 dev->open = de620_open; 887 dev->stop = de620_close; 888 dev->hard_start_xmit = de620_start_xmit; 889 dev->tx_timeout = de620_timeout; 890 dev->watchdog_timeo = HZ*2; 891 dev->set_multicast_list = de620_set_multicast_list; 892 893 /* base_addr and irq are already set, see above! */ 894 895 /* dump eeprom */ 896 if (de620_debug) { 897 printk("\nEEPROM contents:\n"); 898 printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size); 899 printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n", 900 nic_data.NodeID[0], nic_data.NodeID[1], 901 nic_data.NodeID[2], nic_data.NodeID[3], 902 nic_data.NodeID[4], nic_data.NodeID[5]); 903 printk("Model = %d\n", nic_data.Model); 904 printk("Media = %d\n", nic_data.Media); 905 printk("SCR = 0x%02x\n", nic_data.SCR); 906 } 907 908 err = register_netdev(dev); 909 if (err) 910 goto out2; 911 return dev; 912 913out2: 914 release_region(dev->base_addr, 3); 915out1: 916 free_netdev(dev); 917out: 918 return ERR_PTR(err); 919} 920 921/********************************** 922 * 923 * Read info from on-board EEPROM 924 * 925 * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_! 926 */ 927#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister); 928 929static unsigned short __init ReadAWord(struct net_device *dev, int from) 930{ 931 unsigned short data; 932 int nbits; 933 934 /* cs [__~~] SET SEND STATE */ 935 /* di [____] */ 936 /* sck [_~~_] */ 937 sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4); 938 939 /* Send the 9-bit address from where we want to read the 16-bit word */ 940 for (nbits = 9; nbits > 0; --nbits, from <<= 1) { 941 if (from & 0x0100) { /* bit set? */ 942 /* cs [~~~~] SEND 1 */ 943 /* di [~~~~] */ 944 /* sck [_~~_] */ 945 sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6); 946 } 947 else { 948 /* cs [~~~~] SEND 0 */ 949 /* di [____] */ 950 /* sck [_~~_] */ 951 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4); 952 } 953 } 954 955 /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */ 956 for (data = 0, nbits = 16; nbits > 0; --nbits) { 957 /* cs [~~~~] SEND 0 */ 958 /* di [____] */ 959 /* sck [_~~_] */ 960 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4); 961 data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7); 962 } 963 /* cs [____] RESET SEND STATE */ 964 /* di [____] */ 965 /* sck [_~~_] */ 966 sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0); 967 968 return data; 969} 970 971static int __init read_eeprom(struct net_device *dev) 972{ 973 unsigned short wrd; 974 975 /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */ 976 wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */ 977 if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */ 978 return -1; /* Nope, not a DE-620 */ 979 nic_data.NodeID[0] = wrd & 0xff; 980 nic_data.NodeID[1] = wrd >> 8; 981 982 wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */ 983 if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */ 984 return -1; /* Nope, not a DE-620 */ 985 nic_data.NodeID[2] = wrd & 0xff; 986 nic_data.NodeID[3] = wrd >> 8; 987 988 wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */ 989 nic_data.NodeID[4] = wrd & 0xff; 990 nic_data.NodeID[5] = wrd >> 8; 991 992 wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */ 993 nic_data.RAM_Size = (wrd >> 8); 994 995 wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */ 996 nic_data.Model = (wrd & 0xff); 997 998 wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */ 999 nic_data.Media = (wrd & 0xff); 1000 1001 wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */ 1002 nic_data.SCR = (wrd >> 8); 1003 1004 return 0; /* no errors */ 1005} 1006 1007/****************************************************************************** 1008 * 1009 * Loadable module skeleton 1010 * 1011 */ 1012#ifdef MODULE 1013static struct net_device *de620_dev; 1014 1015int init_module(void) 1016{ 1017 de620_dev = de620_probe(-1); 1018 if (IS_ERR(de620_dev)) 1019 return PTR_ERR(de620_dev); 1020 return 0; 1021} 1022 1023void cleanup_module(void) 1024{ 1025 unregister_netdev(de620_dev); 1026 release_region(de620_dev->base_addr, 3); 1027 free_netdev(de620_dev); 1028} 1029#endif /* MODULE */ 1030MODULE_LICENSE("GPL"); 1031 1032 1033/* 1034 * (add '-DMODULE' when compiling as loadable module) 1035 * 1036 * compile-command: 1037 * gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \ 1038 * -fomit-frame-pointer -m486 \ 1039 * -I/usr/src/linux/include -I../../net/inet -c de620.c 1040*/ 1041/* 1042 * Local variables: 1043 * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1044 * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1045 * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1046 * End: 1047 */