Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.23 1046 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 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 *); 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) 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->data points to the start of sk_buff data area */ 701 buffer = skb_put(skb,size); 702 /* copy the packet into the buffer */ 703 de620_read_block(dev, buffer, size); 704 PRINTK(("Read %d bytes\n", size)); 705 skb->protocol=eth_type_trans(skb,dev); 706 netif_rx(skb); /* deliver it "upstairs" */ 707 dev->last_rx = jiffies; 708 /* count all receives */ 709 ((struct net_device_stats *)(dev->priv))->rx_packets++; 710 ((struct net_device_stats *)(dev->priv))->rx_bytes += size; 711 } 712 } 713 714 /* Let's peek ahead to see if we have read the last current packet */ 715 /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */ 716 curr_page = de620_get_register(dev, R_CPR); 717 de620_set_register(dev, W_NPRF, next_rx_page); 718 PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page)); 719 720 return (next_rx_page != curr_page); /* That was slightly tricky... */ 721} 722 723/********************************************* 724 * 725 * Reset the adapter to a known state 726 * 727 */ 728static int adapter_init(struct net_device *dev) 729{ 730 int i; 731 static int was_down; 732 733 if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */ 734 EIPRegister = NCTL0; 735 if (nic_data.Media != 1) 736 EIPRegister |= NIS0; /* not BNC */ 737 } 738 else if (nic_data.Model == 2) { /* UTP */ 739 EIPRegister = NCTL0 | NIS0; 740 } 741 742 if (utp) 743 EIPRegister = NCTL0 | NIS0; 744 if (bnc) 745 EIPRegister = NCTL0; 746 747 de620_send_command(dev, W_CR | RNOP | CLEAR); 748 de620_send_command(dev, W_CR | RNOP); 749 750 de620_set_register(dev, W_SCR, SCR_DEF); 751 /* disable recv to wait init */ 752 de620_set_register(dev, W_TCR, RXOFF); 753 754 /* Set the node ID in the adapter */ 755 for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */ 756 de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]); 757 } 758 759 de620_set_register(dev, W_EIP, EIPRegister); 760 761 next_rx_page = first_rx_page = DE620_RX_START_PAGE; 762 if (nic_data.RAM_Size) 763 last_rx_page = nic_data.RAM_Size - 1; 764 else /* 64k RAM */ 765 last_rx_page = 255; 766 767 de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/ 768 de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */ 769 de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/ 770 de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/ 771 de620_send_command(dev, W_DUMMY); 772 de620_set_delay(dev); 773 774 /* Final sanity check: Anybody out there? */ 775 /* Let's hope some bits from the statusregister make a good check */ 776#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 ) 777#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ) 778 /* success: X 0 0 X 0 0 X X */ 779 /* ignore: EEDI RXGOOD COLS LNKS*/ 780 781 if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) { 782 printk(KERN_ERR "%s: Something has happened to the DE-620! Please check it" 783#ifdef SHUTDOWN_WHEN_LOST 784 " and do a new ifconfig" 785#endif 786 "! (%02x)\n", dev->name, i); 787#ifdef SHUTDOWN_WHEN_LOST 788 /* Goodbye, cruel world... */ 789 dev->flags &= ~IFF_UP; 790 de620_close(dev); 791#endif 792 was_down = 1; 793 return 1; /* failed */ 794 } 795 if (was_down) { 796 printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name); 797 was_down = 0; 798 } 799 800 /* All OK, go ahead... */ 801 de620_set_register(dev, W_TCR, TCR_DEF); 802 803 return 0; /* all ok */ 804} 805 806/****************************************************************************** 807 * 808 * Only start-up code below 809 * 810 */ 811/**************************************** 812 * 813 * Check if there is a DE-620 connected 814 */ 815struct net_device * __init de620_probe(int unit) 816{ 817 byte checkbyte = 0xa5; 818 struct net_device *dev; 819 int err = -ENOMEM; 820 int i; 821 822 dev = alloc_etherdev(sizeof(struct net_device_stats)); 823 if (!dev) 824 goto out; 825 826 SET_MODULE_OWNER(dev); 827 828 spin_lock_init(&de620_lock); 829 830 /* 831 * This is where the base_addr and irq gets set. 832 * Tunable at compile-time and insmod-time 833 */ 834 dev->base_addr = io; 835 dev->irq = irq; 836 837 /* allow overriding parameters on command line */ 838 if (unit >= 0) { 839 sprintf(dev->name, "eth%d", unit); 840 netdev_boot_setup_check(dev); 841 } 842 843 if (de620_debug) 844 printk(version); 845 846 printk(KERN_INFO "D-Link DE-620 pocket adapter"); 847 848 if (!request_region(dev->base_addr, 3, "de620")) { 849 printk(" io 0x%3lX, which is busy.\n", dev->base_addr); 850 err = -EBUSY; 851 goto out1; 852 } 853 854 /* Initially, configure basic nibble mode, so we can read the EEPROM */ 855 NIC_Cmd = DEF_NIC_CMD; 856 de620_set_register(dev, W_EIP, EIPRegister); 857 858 /* Anybody out there? */ 859 de620_set_register(dev, W_CPR, checkbyte); 860 checkbyte = de620_get_register(dev, R_CPR); 861 862 if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) { 863 printk(" not identified in the printer port\n"); 864 err = -ENODEV; 865 goto out2; 866 } 867 868 /* else, got it! */ 869 printk(", Ethernet Address: %2.2X", 870 dev->dev_addr[0] = nic_data.NodeID[0]); 871 for (i = 1; i < ETH_ALEN; i++) { 872 printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]); 873 dev->broadcast[i] = 0xff; 874 } 875 876 printk(" (%dk RAM,", 877 (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64); 878 879 if (nic_data.Media == 1) 880 printk(" BNC)\n"); 881 else 882 printk(" UTP)\n"); 883 884 dev->get_stats = get_stats; 885 dev->open = de620_open; 886 dev->stop = de620_close; 887 dev->hard_start_xmit = de620_start_xmit; 888 dev->tx_timeout = de620_timeout; 889 dev->watchdog_timeo = HZ*2; 890 dev->set_multicast_list = de620_set_multicast_list; 891 892 /* base_addr and irq are already set, see above! */ 893 894 /* dump eeprom */ 895 if (de620_debug) { 896 printk("\nEEPROM contents:\n"); 897 printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size); 898 printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n", 899 nic_data.NodeID[0], nic_data.NodeID[1], 900 nic_data.NodeID[2], nic_data.NodeID[3], 901 nic_data.NodeID[4], nic_data.NodeID[5]); 902 printk("Model = %d\n", nic_data.Model); 903 printk("Media = %d\n", nic_data.Media); 904 printk("SCR = 0x%02x\n", nic_data.SCR); 905 } 906 907 err = register_netdev(dev); 908 if (err) 909 goto out2; 910 return dev; 911 912out2: 913 release_region(dev->base_addr, 3); 914out1: 915 free_netdev(dev); 916out: 917 return ERR_PTR(err); 918} 919 920/********************************** 921 * 922 * Read info from on-board EEPROM 923 * 924 * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_! 925 */ 926#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister); 927 928static unsigned short __init ReadAWord(struct net_device *dev, int from) 929{ 930 unsigned short data; 931 int nbits; 932 933 /* cs [__~~] SET SEND STATE */ 934 /* di [____] */ 935 /* sck [_~~_] */ 936 sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4); 937 938 /* Send the 9-bit address from where we want to read the 16-bit word */ 939 for (nbits = 9; nbits > 0; --nbits, from <<= 1) { 940 if (from & 0x0100) { /* bit set? */ 941 /* cs [~~~~] SEND 1 */ 942 /* di [~~~~] */ 943 /* sck [_~~_] */ 944 sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6); 945 } 946 else { 947 /* cs [~~~~] SEND 0 */ 948 /* di [____] */ 949 /* sck [_~~_] */ 950 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4); 951 } 952 } 953 954 /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */ 955 for (data = 0, nbits = 16; nbits > 0; --nbits) { 956 /* cs [~~~~] SEND 0 */ 957 /* di [____] */ 958 /* sck [_~~_] */ 959 sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4); 960 data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7); 961 } 962 /* cs [____] RESET SEND STATE */ 963 /* di [____] */ 964 /* sck [_~~_] */ 965 sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0); 966 967 return data; 968} 969 970static int __init read_eeprom(struct net_device *dev) 971{ 972 unsigned short wrd; 973 974 /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */ 975 wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */ 976 if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */ 977 return -1; /* Nope, not a DE-620 */ 978 nic_data.NodeID[0] = wrd & 0xff; 979 nic_data.NodeID[1] = wrd >> 8; 980 981 wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */ 982 if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */ 983 return -1; /* Nope, not a DE-620 */ 984 nic_data.NodeID[2] = wrd & 0xff; 985 nic_data.NodeID[3] = wrd >> 8; 986 987 wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */ 988 nic_data.NodeID[4] = wrd & 0xff; 989 nic_data.NodeID[5] = wrd >> 8; 990 991 wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */ 992 nic_data.RAM_Size = (wrd >> 8); 993 994 wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */ 995 nic_data.Model = (wrd & 0xff); 996 997 wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */ 998 nic_data.Media = (wrd & 0xff); 999 1000 wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */ 1001 nic_data.SCR = (wrd >> 8); 1002 1003 return 0; /* no errors */ 1004} 1005 1006/****************************************************************************** 1007 * 1008 * Loadable module skeleton 1009 * 1010 */ 1011#ifdef MODULE 1012static struct net_device *de620_dev; 1013 1014int __init init_module(void) 1015{ 1016 de620_dev = de620_probe(-1); 1017 if (IS_ERR(de620_dev)) 1018 return PTR_ERR(de620_dev); 1019 return 0; 1020} 1021 1022void cleanup_module(void) 1023{ 1024 unregister_netdev(de620_dev); 1025 release_region(de620_dev->base_addr, 3); 1026 free_netdev(de620_dev); 1027} 1028#endif /* MODULE */ 1029MODULE_LICENSE("GPL"); 1030 1031 1032/* 1033 * (add '-DMODULE' when compiling as loadable module) 1034 * 1035 * compile-command: 1036 * gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \ 1037 * -fomit-frame-pointer -m486 \ 1038 * -I/usr/src/linux/include -I../../net/inet -c de620.c 1039*/ 1040/* 1041 * Local variables: 1042 * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1043 * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1044 * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c" 1045 * End: 1046 */