|
|
1.1 ! root 1: static const char *version = ! 2: "de600.c: $Revision: 1.1 $, Bjorn Ekwall ([email protected])\n"; ! 3: /* ! 4: * de600.c ! 5: * ! 6: * Linux driver for the D-Link DE-600 Ethernet pocket adapter. ! 7: * ! 8: * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall ! 9: * The Author may be reached as [email protected] ! 10: * ! 11: * Based on adapter information gathered from DE600.ASM by D-Link Inc., ! 12: * as included on disk C in the v.2.11 of PC/TCP from FTP Software. ! 13: * For DE600.asm: ! 14: * Portions (C) Copyright 1990 D-Link, Inc. ! 15: * Copyright, 1988-1992, Russell Nelson, Crynwr Software ! 16: * ! 17: * Adapted to the sample network driver core for linux, ! 18: * written by: Donald Becker <[email protected]> ! 19: * C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715 ! 20: * ! 21: * compile-command: ! 22: * "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer \ ! 23: * -m486 -c de600.c ! 24: * ! 25: **************************************************************/ ! 26: /* ! 27: * This program is free software; you can redistribute it and/or modify ! 28: * it under the terms of the GNU General Public License as published by ! 29: * the Free Software Foundation; either version 2, or (at your option) ! 30: * any later version. ! 31: * ! 32: * This program is distributed in the hope that it will be useful, ! 33: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 34: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 35: * GNU General Public License for more details. ! 36: * ! 37: * You should have received a copy of the GNU General Public License ! 38: * along with this program; if not, write to the Free Software ! 39: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 40: * ! 41: **************************************************************/ ! 42: /* Add another "; SLOW_DOWN_IO" here if your adapter won't work OK: */ ! 43: #define DE600_SLOW_DOWN SLOW_DOWN_IO; SLOW_DOWN_IO; SLOW_DOWN_IO ! 44: ! 45: /* ! 46: * If you still have trouble reading/writing to the adapter, ! 47: * modify the following "#define": (see <asm/io.h> for more info) ! 48: #define REALLY_SLOW_IO ! 49: */ ! 50: #define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */ ! 51: ! 52: /* ! 53: * If you want to enable automatic continuous checking for the DE600, ! 54: * keep this #define enabled. ! 55: * It doesn't cost much per packet, so I think it is worth it! ! 56: * If you disagree, comment away the #define, and live with it... ! 57: * ! 58: */ ! 59: #define CHECK_LOST_DE600 ! 60: ! 61: /* ! 62: * Enable this #define if you want the adapter to do a "ifconfig down" on ! 63: * itself when we have detected that something is possibly wrong with it. ! 64: * The default behaviour is to retry with "adapter_init()" until success. ! 65: * This should be used for debugging purposes only. ! 66: * (Depends on the CHECK_LOST_DE600 above) ! 67: * ! 68: */ ! 69: #define SHUTDOWN_WHEN_LOST ! 70: ! 71: /* ! 72: * See comment at "de600_rspace()"! ! 73: * This is an *ugly* hack, but for now it achieves its goal of ! 74: * faking a TCP flow-control that will not flood the poor DE600. ! 75: * ! 76: * Tricks TCP to announce a small max window (max 2 fast packets please :-) ! 77: * ! 78: * Comment away at your own risk! ! 79: * ! 80: * Update: Use the more general per-device maxwindow parameter instead. ! 81: */ ! 82: #undef FAKE_SMALL_MAX ! 83: ! 84: /* use 0 for production, 1 for verification, >2 for debug */ ! 85: #ifdef DE600_DEBUG ! 86: #define PRINTK(x) if (de600_debug >= 2) printk x ! 87: #else ! 88: #define DE600_DEBUG 0 ! 89: #define PRINTK(x) /**/ ! 90: #endif ! 91: unsigned int de600_debug = DE600_DEBUG; ! 92: ! 93: #include <linux/module.h> ! 94: ! 95: #include <linux/kernel.h> ! 96: #include <linux/sched.h> ! 97: #include <linux/types.h> ! 98: #include <linux/fcntl.h> ! 99: #include <linux/string.h> ! 100: #include <linux/interrupt.h> ! 101: #include <linux/ioport.h> ! 102: #include <asm/io.h> ! 103: #include <linux/in.h> ! 104: #include <linux/ptrace.h> ! 105: #include <asm/system.h> ! 106: #include <linux/errno.h> ! 107: ! 108: #include <linux/inet.h> ! 109: #include <linux/netdevice.h> ! 110: #include <linux/etherdevice.h> ! 111: #include <linux/skbuff.h> ! 112: ! 113: #ifdef FAKE_SMALL_MAX ! 114: static unsigned long de600_rspace(struct sock *sk); ! 115: #include <net/sock.h> ! 116: #endif ! 117: ! 118: #define netstats enet_statistics ! 119: typedef unsigned char byte; ! 120: ! 121: /************************************************** ! 122: * * ! 123: * Definition of D-Link Ethernet Pocket adapter * ! 124: * * ! 125: **************************************************/ ! 126: /* ! 127: * D-Link Ethernet pocket adapter ports ! 128: */ ! 129: /* ! 130: * OK, so I'm cheating, but there are an awful lot of ! 131: * reads and writes in order to get anything in and out ! 132: * of the DE-600 with 4 bits at a time in the parallel port, ! 133: * so every saved instruction really helps :-) ! 134: * ! 135: * That is, I don't care what the device struct says ! 136: * but hope that Space.c will keep the rest of the drivers happy. ! 137: */ ! 138: #ifndef DE600_IO ! 139: #define DE600_IO 0x378 ! 140: #endif ! 141: ! 142: #define DATA_PORT (DE600_IO) ! 143: #define STATUS_PORT (DE600_IO + 1) ! 144: #define COMMAND_PORT (DE600_IO + 2) ! 145: ! 146: #ifndef DE600_IRQ ! 147: #define DE600_IRQ 7 ! 148: #endif ! 149: /* ! 150: * It really should look like this, and autoprobing as well... ! 151: * ! 152: #define DATA_PORT (dev->base_addr + 0) ! 153: #define STATUS_PORT (dev->base_addr + 1) ! 154: #define COMMAND_PORT (dev->base_addr + 2) ! 155: #define DE600_IRQ dev->irq ! 156: */ ! 157: ! 158: /* ! 159: * D-Link COMMAND_PORT commands ! 160: */ ! 161: #define SELECT_NIC 0x04 /* select Network Interface Card */ ! 162: #define SELECT_PRN 0x1c /* select Printer */ ! 163: #define NML_PRN 0xec /* normal Printer situation */ ! 164: #define IRQEN 0x10 /* enable IRQ line */ ! 165: ! 166: /* ! 167: * D-Link STATUS_PORT ! 168: */ ! 169: #define RX_BUSY 0x80 ! 170: #define RX_GOOD 0x40 ! 171: #define TX_FAILED16 0x10 ! 172: #define TX_BUSY 0x08 ! 173: ! 174: /* ! 175: * D-Link DATA_PORT commands ! 176: * command in low 4 bits ! 177: * data in high 4 bits ! 178: * select current data nibble with HI_NIBBLE bit ! 179: */ ! 180: #define WRITE_DATA 0x00 /* write memory */ ! 181: #define READ_DATA 0x01 /* read memory */ ! 182: #define STATUS 0x02 /* read status register */ ! 183: #define COMMAND 0x03 /* write command register (see COMMAND below) */ ! 184: #define NULL_COMMAND 0x04 /* null command */ ! 185: #define RX_LEN 0x05 /* read received packet length */ ! 186: #define TX_ADDR 0x06 /* set adapter transmit memory address */ ! 187: #define RW_ADDR 0x07 /* set adapter read/write memory address */ ! 188: #define HI_NIBBLE 0x08 /* read/write the high nibble of data, ! 189: or-ed with rest of command */ ! 190: ! 191: /* ! 192: * command register, accessed through DATA_PORT with low bits = COMMAND ! 193: */ ! 194: #define RX_ALL 0x01 /* PROMISCUOUS */ ! 195: #define RX_BP 0x02 /* default: BROADCAST & PHYSICAL ADDRESS */ ! 196: #define RX_MBP 0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */ ! 197: ! 198: #define TX_ENABLE 0x04 /* bit 2 */ ! 199: #define RX_ENABLE 0x08 /* bit 3 */ ! 200: ! 201: #define RESET 0x80 /* set bit 7 high */ ! 202: #define STOP_RESET 0x00 /* set bit 7 low */ ! 203: ! 204: /* ! 205: * data to command register ! 206: * (high 4 bits in write to DATA_PORT) ! 207: */ ! 208: #define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */ ! 209: #define RX_BASE_PAGE 0x20 /* bit 5, always set when specifying RX_ADDR */ ! 210: #define FLIP_IRQ 0x40 /* bit 6 */ ! 211: ! 212: /* ! 213: * D-Link adapter internal memory: ! 214: * ! 215: * 0-2K 1:st transmit page (send from pointer up to 2K) ! 216: * 2-4K 2:nd transmit page (send from pointer up to 4K) ! 217: * ! 218: * 4-6K 1:st receive page (data from 4K upwards) ! 219: * 6-8K 2:nd receive page (data from 6K upwards) ! 220: * ! 221: * 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address) ! 222: */ ! 223: #define MEM_2K 0x0800 /* 2048 */ ! 224: #define MEM_4K 0x1000 /* 4096 */ ! 225: #define MEM_6K 0x1800 /* 6144 */ ! 226: #define NODE_ADDRESS 0x2000 /* 8192 */ ! 227: ! 228: #define RUNT 60 /* Too small Ethernet packet */ ! 229: ! 230: /************************************************** ! 231: * * ! 232: * End of definition * ! 233: * * ! 234: **************************************************/ ! 235: ! 236: /* ! 237: * Index to functions, as function prototypes. ! 238: */ ! 239: /* Routines used internally. (See "convenience macros") */ ! 240: static byte de600_read_status(struct device *dev); ! 241: static byte de600_read_byte(unsigned char type, struct device *dev); ! 242: ! 243: /* Put in the device structure. */ ! 244: static int de600_open(struct device *dev); ! 245: static int de600_close(struct device *dev); ! 246: static struct netstats *get_stats(struct device *dev); ! 247: static int de600_start_xmit(struct sk_buff *skb, struct device *dev); ! 248: ! 249: /* Dispatch from interrupts. */ ! 250: static void de600_interrupt(int irq, void *dev_id, struct pt_regs *regs); ! 251: static int de600_tx_intr(struct device *dev, int irq_status); ! 252: static void de600_rx_intr(struct device *dev); ! 253: ! 254: /* Initialization */ ! 255: static void trigger_interrupt(struct device *dev); ! 256: int de600_probe(struct device *dev); ! 257: static int adapter_init(struct device *dev); ! 258: ! 259: /* ! 260: * D-Link driver variables: ! 261: */ ! 262: static volatile int rx_page = 0; ! 263: ! 264: #define TX_PAGES 2 ! 265: static volatile int tx_fifo[TX_PAGES]; ! 266: static volatile int tx_fifo_in = 0; ! 267: static volatile int tx_fifo_out = 0; ! 268: static volatile int free_tx_pages = TX_PAGES; ! 269: static int was_down = 0; ! 270: ! 271: /* ! 272: * Convenience macros/functions for D-Link adapter ! 273: */ ! 274: ! 275: #define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN ! 276: #define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN ! 277: ! 278: /* Thanks for hints from Mark Burton <[email protected]> */ ! 279: #define de600_put_byte(data) ( \ ! 280: outb_p(((data) << 4) | WRITE_DATA , DATA_PORT), \ ! 281: outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT)) ! 282: ! 283: /* ! 284: * The first two outb_p()'s below could perhaps be deleted if there ! 285: * would be more delay in the last two. Not certain about it yet... ! 286: */ ! 287: #define de600_put_command(cmd) ( \ ! 288: outb_p(( rx_page << 4) | COMMAND , DATA_PORT), \ ! 289: outb_p(( rx_page & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \ ! 290: outb_p(((rx_page | cmd) << 4) | COMMAND , DATA_PORT), \ ! 291: outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT)) ! 292: ! 293: #define de600_setup_address(addr,type) ( \ ! 294: outb_p((((addr) << 4) & 0xf0) | type , DATA_PORT), \ ! 295: outb_p(( (addr) & 0xf0) | type | HI_NIBBLE, DATA_PORT), \ ! 296: outb_p((((addr) >> 4) & 0xf0) | type , DATA_PORT), \ ! 297: outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT)) ! 298: ! 299: #define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K)) ! 300: ! 301: /* Flip bit, only 2 pages */ ! 302: #define next_rx_page() (rx_page ^= RX_PAGE2_SELECT) ! 303: ! 304: #define tx_page_adr(a) (((a) + 1) * MEM_2K) ! 305: ! 306: static inline byte ! 307: de600_read_status(struct device *dev) ! 308: { ! 309: byte status; ! 310: ! 311: outb_p(STATUS, DATA_PORT); ! 312: status = inb(STATUS_PORT); ! 313: outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT); ! 314: ! 315: return status; ! 316: } ! 317: ! 318: static inline byte ! 319: de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros */ ! 320: byte lo; ! 321: ! 322: (void)outb_p((type), DATA_PORT); ! 323: lo = ((unsigned char)inb(STATUS_PORT)) >> 4; ! 324: (void)outb_p((type) | HI_NIBBLE, DATA_PORT); ! 325: return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo; ! 326: } ! 327: ! 328: /* ! 329: * Open/initialize the board. This is called (in the current kernel) ! 330: * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1). ! 331: * ! 332: * This routine should set everything up anew at each open, even ! 333: * registers that "should" only need to be set once at boot, so that ! 334: * there is a non-reboot way to recover if something goes wrong. ! 335: */ ! 336: static int ! 337: de600_open(struct device *dev) ! 338: { ! 339: if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600", NULL)) { ! 340: printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ); ! 341: return 1; ! 342: } ! 343: irq2dev_map[DE600_IRQ] = dev; ! 344: ! 345: MOD_INC_USE_COUNT; ! 346: dev->start = 1; ! 347: if (adapter_init(dev)) { ! 348: return 1; ! 349: } ! 350: ! 351: return 0; ! 352: } ! 353: ! 354: /* ! 355: * The inverse routine to de600_open(). ! 356: */ ! 357: static int ! 358: de600_close(struct device *dev) ! 359: { ! 360: select_nic(); ! 361: rx_page = 0; ! 362: de600_put_command(RESET); ! 363: de600_put_command(STOP_RESET); ! 364: de600_put_command(0); ! 365: select_prn(); ! 366: ! 367: if (dev->start) { ! 368: free_irq(DE600_IRQ, NULL); ! 369: irq2dev_map[DE600_IRQ] = NULL; ! 370: dev->start = 0; ! 371: MOD_DEC_USE_COUNT; ! 372: } ! 373: return 0; ! 374: } ! 375: ! 376: static struct netstats * ! 377: get_stats(struct device *dev) ! 378: { ! 379: return (struct netstats *)(dev->priv); ! 380: } ! 381: ! 382: static inline void ! 383: trigger_interrupt(struct device *dev) ! 384: { ! 385: de600_put_command(FLIP_IRQ); ! 386: select_prn(); ! 387: DE600_SLOW_DOWN; ! 388: select_nic(); ! 389: de600_put_command(0); ! 390: } ! 391: ! 392: /* ! 393: * Copy a buffer to the adapter transmit page memory. ! 394: * Start sending. ! 395: */ ! 396: static int ! 397: de600_start_xmit(struct sk_buff *skb, struct device *dev) ! 398: { ! 399: int transmit_from; ! 400: int len; ! 401: int tickssofar; ! 402: byte *buffer = skb->data; ! 403: ! 404: /* ! 405: * If some higher layer thinks we've missed a ! 406: * tx-done interrupt we are passed NULL. ! 407: * Caution: dev_tint() handles the cli()/sti() itself. ! 408: */ ! 409: ! 410: if (skb == NULL) { ! 411: dev_tint(dev); ! 412: return 0; ! 413: } ! 414: ! 415: if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */ ! 416: tickssofar = jiffies - dev->trans_start; ! 417: ! 418: if (tickssofar < 5) ! 419: return 1; ! 420: ! 421: /* else */ ! 422: printk("%s: transmit timed out (%d), %s?\n", ! 423: dev->name, ! 424: tickssofar, ! 425: "network cable problem" ! 426: ); ! 427: /* Restart the adapter. */ ! 428: if (adapter_init(dev)) { ! 429: return 1; ! 430: } ! 431: } ! 432: ! 433: /* Start real output */ ! 434: PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages)); ! 435: ! 436: if ((len = skb->len) < RUNT) ! 437: len = RUNT; ! 438: ! 439: cli(); ! 440: select_nic(); ! 441: tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len; ! 442: tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */ ! 443: ! 444: #ifdef CHECK_LOST_DE600 ! 445: /* This costs about 40 instructions per packet... */ ! 446: de600_setup_address(NODE_ADDRESS, RW_ADDR); ! 447: de600_read_byte(READ_DATA, dev); ! 448: if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) { ! 449: if (adapter_init(dev)) { ! 450: sti(); ! 451: return 1; ! 452: } ! 453: } ! 454: #endif ! 455: ! 456: de600_setup_address(transmit_from, RW_ADDR); ! 457: for ( ; len > 0; --len, ++buffer) ! 458: de600_put_byte(*buffer); ! 459: ! 460: if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */ ! 461: dev->trans_start = jiffies; ! 462: dev->tbusy = 0; /* allow more packets into adapter */ ! 463: /* Send page and generate a faked interrupt */ ! 464: de600_setup_address(transmit_from, TX_ADDR); ! 465: de600_put_command(TX_ENABLE); ! 466: } ! 467: else { ! 468: dev->tbusy = !free_tx_pages; ! 469: select_prn(); ! 470: } ! 471: ! 472: sti(); /* interrupts back on */ ! 473: ! 474: #ifdef FAKE_SMALL_MAX ! 475: /* This will "patch" the socket TCP proto at an early moment */ ! 476: if (skb->sk && (skb->sk->protocol == IPPROTO_TCP) && ! 477: (skb->sk->prot->rspace != &de600_rspace)) ! 478: skb->sk->prot->rspace = de600_rspace; /* Ugh! */ ! 479: #endif ! 480: ! 481: dev_kfree_skb (skb, FREE_WRITE); ! 482: ! 483: return 0; ! 484: } ! 485: ! 486: /* ! 487: * The typical workload of the driver: ! 488: * Handle the network interface interrupts. ! 489: */ ! 490: static void ! 491: de600_interrupt(int irq, void *dev_id, struct pt_regs * regs) ! 492: { ! 493: struct device *dev = irq2dev_map[irq]; ! 494: byte irq_status; ! 495: int retrig = 0; ! 496: int boguscount = 0; ! 497: ! 498: /* This might just as well be deleted now, no crummy drivers present :-) */ ! 499: if ((dev == NULL) || (dev->start == 0) || (DE600_IRQ != irq)) { ! 500: printk("%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq); ! 501: return; ! 502: } ! 503: ! 504: dev->interrupt = 1; ! 505: select_nic(); ! 506: irq_status = de600_read_status(dev); ! 507: ! 508: do { ! 509: PRINTK(("de600_interrupt (%02X)\n", irq_status)); ! 510: ! 511: if (irq_status & RX_GOOD) ! 512: de600_rx_intr(dev); ! 513: else if (!(irq_status & RX_BUSY)) ! 514: de600_put_command(RX_ENABLE); ! 515: ! 516: /* Any transmission in progress? */ ! 517: if (free_tx_pages < TX_PAGES) ! 518: retrig = de600_tx_intr(dev, irq_status); ! 519: else ! 520: retrig = 0; ! 521: ! 522: irq_status = de600_read_status(dev); ! 523: } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) ); ! 524: /* ! 525: * Yeah, it _looks_ like busy waiting, smells like busy waiting ! 526: * and I know it's not PC, but please, it will only occur once ! 527: * in a while and then only for a loop or so (< 1ms for sure!) ! 528: */ ! 529: ! 530: /* Enable adapter interrupts */ ! 531: dev->interrupt = 0; ! 532: select_prn(); ! 533: ! 534: if (retrig) ! 535: trigger_interrupt(dev); ! 536: ! 537: sti(); ! 538: return; ! 539: } ! 540: ! 541: static int ! 542: de600_tx_intr(struct device *dev, int irq_status) ! 543: { ! 544: /* ! 545: * Returns 1 if tx still not done ! 546: */ ! 547: ! 548: mark_bh(NET_BH); ! 549: /* Check if current transmission is done yet */ ! 550: if (irq_status & TX_BUSY) ! 551: return 1; /* tx not done, try again */ ! 552: ! 553: /* else */ ! 554: /* If last transmission OK then bump fifo index */ ! 555: if (!(irq_status & TX_FAILED16)) { ! 556: tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES; ! 557: ++free_tx_pages; ! 558: ((struct netstats *)(dev->priv))->tx_packets++; ! 559: dev->tbusy = 0; ! 560: } ! 561: ! 562: /* More to send, or resend last packet? */ ! 563: if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) { ! 564: dev->trans_start = jiffies; ! 565: de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR); ! 566: de600_put_command(TX_ENABLE); ! 567: return 1; ! 568: } ! 569: /* else */ ! 570: ! 571: return 0; ! 572: } ! 573: ! 574: /* ! 575: * We have a good packet, get it out of the adapter. ! 576: */ ! 577: static void ! 578: de600_rx_intr(struct device *dev) ! 579: { ! 580: struct sk_buff *skb; ! 581: int i; ! 582: int read_from; ! 583: int size; ! 584: register unsigned char *buffer; ! 585: ! 586: cli(); ! 587: /* Get size of received packet */ ! 588: size = de600_read_byte(RX_LEN, dev); /* low byte */ ! 589: size += (de600_read_byte(RX_LEN, dev) << 8); /* high byte */ ! 590: size -= 4; /* Ignore trailing 4 CRC-bytes */ ! 591: ! 592: /* Tell adapter where to store next incoming packet, enable receiver */ ! 593: read_from = rx_page_adr(); ! 594: next_rx_page(); ! 595: de600_put_command(RX_ENABLE); ! 596: sti(); ! 597: ! 598: if ((size < 32) || (size > 1535)) { ! 599: printk("%s: Bogus packet size %d.\n", dev->name, size); ! 600: if (size > 10000) ! 601: adapter_init(dev); ! 602: return; ! 603: } ! 604: ! 605: skb = dev_alloc_skb(size+2); ! 606: sti(); ! 607: if (skb == NULL) { ! 608: printk("%s: Couldn't allocate a sk_buff of size %d.\n", ! 609: dev->name, size); ! 610: return; ! 611: } ! 612: /* else */ ! 613: ! 614: skb->dev = dev; ! 615: skb_reserve(skb,2); /* Align */ ! 616: ! 617: /* 'skb->data' points to the start of sk_buff data area. */ ! 618: buffer = skb_put(skb,size); ! 619: ! 620: /* copy the packet into the buffer */ ! 621: de600_setup_address(read_from, RW_ADDR); ! 622: for (i = size; i > 0; --i, ++buffer) ! 623: *buffer = de600_read_byte(READ_DATA, dev); ! 624: ! 625: ((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */ ! 626: ! 627: skb->protocol=eth_type_trans(skb,dev); ! 628: ! 629: netif_rx(skb); ! 630: /* ! 631: * If any worth-while packets have been received, netif_rx() ! 632: * has done a mark_bh(INET_BH) for us and will work on them ! 633: * when we get to the bottom-half routine. ! 634: */ ! 635: } ! 636: ! 637: int ! 638: de600_probe(struct device *dev) ! 639: { ! 640: int i; ! 641: static struct netstats de600_netstats; ! 642: /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/ ! 643: ! 644: printk("%s: D-Link DE-600 pocket adapter", dev->name); ! 645: /* Alpha testers must have the version number to report bugs. */ ! 646: if (de600_debug > 1) ! 647: printk(version); ! 648: ! 649: /* probe for adapter */ ! 650: rx_page = 0; ! 651: select_nic(); ! 652: (void)de600_read_status(dev); ! 653: de600_put_command(RESET); ! 654: de600_put_command(STOP_RESET); ! 655: if (de600_read_status(dev) & 0xf0) { ! 656: printk(": not at I/O %#3x.\n", DATA_PORT); ! 657: return ENODEV; ! 658: } ! 659: ! 660: /* ! 661: * Maybe we found one, ! 662: * have to check if it is a D-Link DE-600 adapter... ! 663: */ ! 664: ! 665: /* Get the adapter ethernet address from the ROM */ ! 666: de600_setup_address(NODE_ADDRESS, RW_ADDR); ! 667: for (i = 0; i < ETH_ALEN; i++) { ! 668: dev->dev_addr[i] = de600_read_byte(READ_DATA, dev); ! 669: dev->broadcast[i] = 0xff; ! 670: } ! 671: ! 672: /* Check magic code */ ! 673: if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) { ! 674: /* OK, install real address */ ! 675: dev->dev_addr[0] = 0x00; ! 676: dev->dev_addr[1] = 0x80; ! 677: dev->dev_addr[2] = 0xc8; ! 678: dev->dev_addr[3] &= 0x0f; ! 679: dev->dev_addr[3] |= 0x70; ! 680: } else { ! 681: printk(" not identified in the printer port\n"); ! 682: return ENODEV; ! 683: } ! 684: ! 685: #if 0 /* Not yet */ ! 686: if (check_region(DE600_IO, 3)) { ! 687: printk(", port 0x%x busy\n", DE600_IO); ! 688: return EBUSY; ! 689: } ! 690: #endif ! 691: request_region(DE600_IO, 3, "de600"); ! 692: ! 693: printk(", Ethernet Address: %02X", dev->dev_addr[0]); ! 694: for (i = 1; i < ETH_ALEN; i++) ! 695: printk(":%02X",dev->dev_addr[i]); ! 696: printk("\n"); ! 697: ! 698: /* Initialize the device structure. */ ! 699: /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/ ! 700: dev->priv = &de600_netstats; ! 701: ! 702: memset(dev->priv, 0, sizeof(struct netstats)); ! 703: dev->get_stats = get_stats; ! 704: ! 705: dev->open = de600_open; ! 706: dev->stop = de600_close; ! 707: dev->hard_start_xmit = &de600_start_xmit; ! 708: ! 709: ether_setup(dev); ! 710: ! 711: dev->flags&=~IFF_MULTICAST; ! 712: ! 713: select_prn(); ! 714: return 0; ! 715: } ! 716: ! 717: static int ! 718: adapter_init(struct device *dev) ! 719: { ! 720: int i; ! 721: long flags; ! 722: ! 723: save_flags(flags); ! 724: cli(); ! 725: ! 726: select_nic(); ! 727: rx_page = 0; /* used by RESET */ ! 728: de600_put_command(RESET); ! 729: de600_put_command(STOP_RESET); ! 730: #ifdef CHECK_LOST_DE600 ! 731: /* Check if it is still there... */ ! 732: /* Get the some bytes of the adapter ethernet address from the ROM */ ! 733: de600_setup_address(NODE_ADDRESS, RW_ADDR); ! 734: de600_read_byte(READ_DATA, dev); ! 735: if ((de600_read_byte(READ_DATA, dev) != 0xde) || ! 736: (de600_read_byte(READ_DATA, dev) != 0x15)) { ! 737: /* was: if (de600_read_status(dev) & 0xf0) { */ ! 738: printk("Something has happened to the DE-600! Please check it" ! 739: #ifdef SHUTDOWN_WHEN_LOST ! 740: " and do a new ifconfig" ! 741: #endif /* SHUTDOWN_WHEN_LOST */ ! 742: "!\n"); ! 743: #ifdef SHUTDOWN_WHEN_LOST ! 744: /* Goodbye, cruel world... */ ! 745: dev->flags &= ~IFF_UP; ! 746: de600_close(dev); ! 747: #endif /* SHUTDOWN_WHEN_LOST */ ! 748: was_down = 1; ! 749: dev->tbusy = 1; /* Transmit busy... */ ! 750: restore_flags(flags); ! 751: return 1; /* failed */ ! 752: } ! 753: #endif /* CHECK_LOST_DE600 */ ! 754: if (was_down) { ! 755: printk("Thanks, I feel much better now!\n"); ! 756: was_down = 0; ! 757: } ! 758: ! 759: dev->tbusy = 0; /* Transmit busy... */ ! 760: dev->interrupt = 0; ! 761: tx_fifo_in = 0; ! 762: tx_fifo_out = 0; ! 763: free_tx_pages = TX_PAGES; ! 764: ! 765: /* set the ether address. */ ! 766: de600_setup_address(NODE_ADDRESS, RW_ADDR); ! 767: for (i = 0; i < ETH_ALEN; i++) ! 768: de600_put_byte(dev->dev_addr[i]); ! 769: ! 770: /* where to start saving incoming packets */ ! 771: rx_page = RX_BP | RX_BASE_PAGE; ! 772: de600_setup_address(MEM_4K, RW_ADDR); ! 773: /* Enable receiver */ ! 774: de600_put_command(RX_ENABLE); ! 775: select_prn(); ! 776: restore_flags(flags); ! 777: ! 778: return 0; /* OK */ ! 779: } ! 780: ! 781: #ifdef FAKE_SMALL_MAX ! 782: /* ! 783: * The new router code (coming soon 8-) ) will fix this properly. ! 784: */ ! 785: #define DE600_MIN_WINDOW 1024 ! 786: #define DE600_MAX_WINDOW 2048 ! 787: #define DE600_TCP_WINDOW_DIFF 1024 ! 788: /* ! 789: * Copied from "net/inet/sock.c" ! 790: * ! 791: * Sets a lower max receive window in order to achieve <= 2 ! 792: * packets arriving at the adapter in fast succession. ! 793: * (No way that a DE-600 can keep up with a net saturated ! 794: * with packets homing in on it :-( ) ! 795: * ! 796: * Since there are only 2 receive buffers in the DE-600 ! 797: * and it takes some time to copy from the adapter, ! 798: * this is absolutely necessary for any TCP performance whatsoever! ! 799: * ! 800: * Note that the returned window info will never be smaller than ! 801: * DE600_MIN_WINDOW, i.e. 1024 ! 802: * This differs from the standard function, that can return an ! 803: * arbitrarily small window! ! 804: */ ! 805: #define min(a,b) ((a)<(b)?(a):(b)) ! 806: static unsigned long ! 807: de600_rspace(struct sock *sk) ! 808: { ! 809: int amt; ! 810: ! 811: if (sk != NULL) { ! 812: /* ! 813: * Hack! You might want to play with commenting away the following line, ! 814: * if you know what you do! ! 815: sk->max_unacked = DE600_MAX_WINDOW - DE600_TCP_WINDOW_DIFF; ! 816: */ ! 817: ! 818: if (sk->rmem_alloc >= sk->rcvbuf-2*DE600_MIN_WINDOW) return(0); ! 819: amt = min((sk->rcvbuf-sk->rmem_alloc)/2/*-DE600_MIN_WINDOW*/, DE600_MAX_WINDOW); ! 820: if (amt < 0) return(0); ! 821: return(amt); ! 822: } ! 823: return(0); ! 824: } ! 825: #endif ! 826: ! 827: #ifdef MODULE ! 828: static char nullname[8]; ! 829: static struct device de600_dev = { ! 830: nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe }; ! 831: ! 832: int ! 833: init_module(void) ! 834: { ! 835: if (register_netdev(&de600_dev) != 0) ! 836: return -EIO; ! 837: return 0; ! 838: } ! 839: ! 840: void ! 841: cleanup_module(void) ! 842: { ! 843: unregister_netdev(&de600_dev); ! 844: release_region(DE600_IO, 3); ! 845: } ! 846: #endif /* MODULE */ ! 847: /* ! 848: * Local variables: ! 849: * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c" ! 850: * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c" ! 851: * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c" ! 852: * End: ! 853: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.