|
|
1.1 ! root 1: /* seeq8005.c: A network driver for linux. */ ! 2: /* ! 3: Based on skeleton.c, ! 4: Written 1993-94 by Donald Becker. ! 5: See the skeleton.c file for further copyright information. ! 6: ! 7: This software may be used and distributed according to the terms ! 8: of the GNU Public License, incorporated herein by reference. ! 9: ! 10: The author may be reached as [email protected] ! 11: ! 12: This file is a network device driver for the SEEQ 8005 chipset and ! 13: the Linux operating system. ! 14: ! 15: */ ! 16: ! 17: static const char *version = ! 18: "seeq8005.c:v1.00 8/07/95 Hamish Coleman ([email protected])\n"; ! 19: ! 20: /* ! 21: Sources: ! 22: SEEQ 8005 databook ! 23: ! 24: Version history: ! 25: 1.00 Public release. cosmetic changes (no warnings now) ! 26: 0.68 Turning per- packet,interrupt debug messages off - testing for release. ! 27: 0.67 timing problems/bad buffer reads seem to be fixed now ! 28: 0.63 *!@$ protocol=eth_type_trans -- now packets flow ! 29: 0.56 Send working ! 30: 0.48 Receive working ! 31: */ ! 32: ! 33: #include <linux/kernel.h> ! 34: #include <linux/sched.h> ! 35: #include <linux/types.h> ! 36: #include <linux/fcntl.h> ! 37: #include <linux/interrupt.h> ! 38: #include <linux/ptrace.h> ! 39: #include <linux/ioport.h> ! 40: #include <linux/in.h> ! 41: #include <linux/malloc.h> ! 42: #include <linux/string.h> ! 43: #include <asm/system.h> ! 44: #include <asm/bitops.h> ! 45: #include <asm/io.h> ! 46: #include <asm/dma.h> ! 47: #include <linux/errno.h> ! 48: ! 49: #include <linux/netdevice.h> ! 50: #include <linux/etherdevice.h> ! 51: #include <linux/skbuff.h> ! 52: #include "seeq8005.h" ! 53: ! 54: /* First, a few definitions that the brave might change. */ ! 55: /* A zero-terminated list of I/O addresses to be probed. */ ! 56: static unsigned int seeq8005_portlist[] = ! 57: { 0x300, 0x320, 0x340, 0x360, 0}; ! 58: ! 59: /* use 0 for production, 1 for verification, >2 for debug */ ! 60: #ifndef NET_DEBUG ! 61: #define NET_DEBUG 1 ! 62: #endif ! 63: static unsigned int net_debug = NET_DEBUG; ! 64: ! 65: /* Information that need to be kept for each board. */ ! 66: struct net_local { ! 67: struct enet_statistics stats; ! 68: unsigned short receive_ptr; /* What address in packet memory do we expect a recv_pkt_header? */ ! 69: long open_time; /* Useless example local info. */ ! 70: }; ! 71: ! 72: /* The station (ethernet) address prefix, used for IDing the board. */ ! 73: #define SA_ADDR0 0x00 ! 74: #define SA_ADDR1 0x80 ! 75: #define SA_ADDR2 0x4b ! 76: ! 77: /* Index to functions, as function prototypes. */ ! 78: ! 79: extern int seeq8005_probe(struct device *dev); ! 80: ! 81: static int seeq8005_probe1(struct device *dev, int ioaddr); ! 82: static int seeq8005_open(struct device *dev); ! 83: static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev); ! 84: static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs); ! 85: static void seeq8005_rx(struct device *dev); ! 86: static int seeq8005_close(struct device *dev); ! 87: static struct enet_statistics *seeq8005_get_stats(struct device *dev); ! 88: static void set_multicast_list(struct device *dev); ! 89: ! 90: /* Example routines you must write ;->. */ ! 91: #define tx_done(dev) (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON) ! 92: extern void hardware_send_packet(struct device *dev, char *buf, int length); ! 93: extern void seeq8005_init(struct device *dev, int startp); ! 94: inline void wait_for_buffer(struct device *dev); ! 95: ! 96: ! 97: /* Check for a network adaptor of this type, and return '0' iff one exists. ! 98: If dev->base_addr == 0, probe all likely locations. ! 99: If dev->base_addr == 1, always return failure. ! 100: If dev->base_addr == 2, allocate space for the device and return success ! 101: (detachable devices only). ! 102: */ ! 103: #ifdef HAVE_DEVLIST ! 104: /* Support for a alternate probe manager, which will eliminate the ! 105: boilerplate below. */ ! 106: struct netdev_entry seeq8005_drv = ! 107: {"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist}; ! 108: #else ! 109: int ! 110: seeq8005_probe(struct device *dev) ! 111: { ! 112: int i; ! 113: int base_addr = dev ? dev->base_addr : 0; ! 114: ! 115: if (base_addr > 0x1ff) /* Check a single specified location. */ ! 116: return seeq8005_probe1(dev, base_addr); ! 117: else if (base_addr != 0) /* Don't probe at all. */ ! 118: return ENXIO; ! 119: ! 120: for (i = 0; seeq8005_portlist[i]; i++) { ! 121: int ioaddr = seeq8005_portlist[i]; ! 122: if (check_region(ioaddr, SEEQ8005_IO_EXTENT)) ! 123: continue; ! 124: if (seeq8005_probe1(dev, ioaddr) == 0) ! 125: return 0; ! 126: } ! 127: ! 128: return ENODEV; ! 129: } ! 130: #endif ! 131: ! 132: /* This is the real probe routine. Linux has a history of friendly device ! 133: probes on the ISA bus. A good device probes avoids doing writes, and ! 134: verifies that the correct device exists and functions. */ ! 135: ! 136: static int seeq8005_probe1(struct device *dev, int ioaddr) ! 137: { ! 138: static unsigned version_printed = 0; ! 139: int i,j; ! 140: unsigned char SA_prom[32]; ! 141: int old_cfg1; ! 142: int old_cfg2; ! 143: int old_stat; ! 144: int old_dmaar; ! 145: int old_rear; ! 146: ! 147: if (net_debug>1) ! 148: printk("seeq8005: probing at 0x%x\n",ioaddr); ! 149: ! 150: old_stat = inw(SEEQ_STATUS); /* read status register */ ! 151: if (old_stat == 0xffff) ! 152: return ENODEV; /* assume that 0xffff == no device */ ! 153: if ( (old_stat & 0x1800) != 0x1800 ) { /* assume that unused bits are 1, as my manual says */ ! 154: if (net_debug>1) { ! 155: printk("seeq8005: reserved stat bits != 0x1800\n"); ! 156: printk(" == 0x%04x\n",old_stat); ! 157: } ! 158: return ENODEV; ! 159: } ! 160: ! 161: old_rear = inw(SEEQ_REA); ! 162: if (old_rear == 0xffff) { ! 163: outw(0,SEEQ_REA); ! 164: if (inw(SEEQ_REA) == 0xffff) { /* assume that 0xffff == no device */ ! 165: return ENODEV; ! 166: } ! 167: } else if ((old_rear & 0xff00) != 0xff00) { /* assume that unused bits are 1 */ ! 168: if (net_debug>1) { ! 169: printk("seeq8005: unused rear bits != 0xff00\n"); ! 170: printk(" == 0x%04x\n",old_rear); ! 171: } ! 172: return ENODEV; ! 173: } ! 174: ! 175: old_cfg2 = inw(SEEQ_CFG2); /* read CFG2 register */ ! 176: old_cfg1 = inw(SEEQ_CFG1); ! 177: old_dmaar = inw(SEEQ_DMAAR); ! 178: ! 179: if (net_debug>4) { ! 180: printk("seeq8005: stat = 0x%04x\n",old_stat); ! 181: printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1); ! 182: printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2); ! 183: printk("seeq8005: raer = 0x%04x\n",old_rear); ! 184: printk("seeq8005: dmaar= 0x%04x\n",old_dmaar); ! 185: } ! 186: ! 187: outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); /* setup for reading PROM */ ! 188: outw( 0, SEEQ_DMAAR); /* set starting PROM address */ ! 189: outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1); /* set buffer to look at PROM */ ! 190: ! 191: ! 192: j=0; ! 193: for(i=0; i <32; i++) { ! 194: j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff; ! 195: } ! 196: ! 197: #if 0 ! 198: /* untested because I only have the one card */ ! 199: if ( (j&0xff) != 0 ) { /* checksum appears to be 8bit = 0 */ ! 200: if (net_debug>1) { /* check this before deciding that we have a card */ ! 201: printk("seeq8005: prom sum error\n"); ! 202: } ! 203: outw( old_stat, SEEQ_STATUS); ! 204: outw( old_dmaar, SEEQ_DMAAR); ! 205: outw( old_cfg1, SEEQ_CFG1); ! 206: return ENODEV; ! 207: } ! 208: #endif ! 209: ! 210: outw( SEEQCFG2_RESET, SEEQ_CFG2); /* reset the card */ ! 211: SLOW_DOWN_IO; /* have to wait 4us after a reset - should be fixed */ ! 212: SLOW_DOWN_IO; ! 213: SLOW_DOWN_IO; ! 214: SLOW_DOWN_IO; ! 215: outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD); ! 216: ! 217: if (net_debug) { ! 218: printk("seeq8005: prom sum = 0x%08x\n",j); ! 219: for(j=0; j<32; j+=16) { ! 220: printk("seeq8005: prom %02x: ",j); ! 221: for(i=0;i<16;i++) { ! 222: printk("%02x ",SA_prom[j|i]); ! 223: } ! 224: printk(" "); ! 225: for(i=0;i<16;i++) { ! 226: if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) { ! 227: printk("%c", SA_prom[j|i]); ! 228: } else { ! 229: printk(" "); ! 230: } ! 231: } ! 232: printk("\n"); ! 233: } ! 234: } ! 235: ! 236: #if 0 ! 237: /* ! 238: * testing the packet buffer memory doesn't work yet ! 239: * but all other buffer accesses do ! 240: * - fixing is not a priority ! 241: */ ! 242: if (net_debug>1) { /* test packet buffer memory */ ! 243: printk("seeq8005: testing packet buffer ... "); ! 244: outw( SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1); ! 245: outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); ! 246: outw( 0 , SEEQ_DMAAR); ! 247: for(i=0;i<32768;i++) { ! 248: outw(0x5a5a, SEEQ_BUFFER); ! 249: } ! 250: j=jiffies+HZ; ! 251: while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && jiffies < j ) ! 252: mb(); ! 253: outw( 0 , SEEQ_DMAAR); ! 254: while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && jiffies < j+HZ) ! 255: mb(); ! 256: if ( (inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT) ! 257: outw( SEEQCMD_WINDOW_INT_ACK | (inw(SEEQ_STATUS)& SEEQCMD_INT_MASK), SEEQ_CMD); ! 258: outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); ! 259: j=0; ! 260: for(i=0;i<32768;i++) { ! 261: if (inw(SEEQ_BUFFER) != 0x5a5a) ! 262: j++; ! 263: } ! 264: if (j) { ! 265: printk("%i\n",j); ! 266: } else { ! 267: printk("ok.\n"); ! 268: } ! 269: } ! 270: #endif ! 271: ! 272: /* Allocate a new 'dev' if needed. */ ! 273: if (dev == NULL) ! 274: dev = init_etherdev(0, sizeof(struct net_local)); ! 275: ! 276: if (net_debug && version_printed++ == 0) ! 277: printk(version); ! 278: ! 279: printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr); ! 280: ! 281: /* Fill in the 'dev' fields. */ ! 282: dev->base_addr = ioaddr; ! 283: ! 284: /* Retrieve and print the ethernet address. */ ! 285: for (i = 0; i < 6; i++) ! 286: printk(" %2.2x", dev->dev_addr[i] = SA_prom[i+6]); ! 287: ! 288: if (dev->irq == 0xff) ! 289: ; /* Do nothing: a user-level program will set it. */ ! 290: else if (dev->irq < 2) { /* "Auto-IRQ" */ ! 291: autoirq_setup(0); ! 292: ! 293: outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD ); ! 294: ! 295: dev->irq = autoirq_report(0); ! 296: ! 297: if (net_debug >= 2) ! 298: printk(" autoirq is %d\n", dev->irq); ! 299: } else if (dev->irq == 2) ! 300: /* Fixup for users that don't know that IRQ 2 is really IRQ 9, ! 301: * or don't know which one to set. ! 302: */ ! 303: dev->irq = 9; ! 304: ! 305: #if 0 ! 306: { ! 307: int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", NULL); ! 308: if (irqval) { ! 309: printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, ! 310: dev->irq, irqval); ! 311: return EAGAIN; ! 312: } ! 313: } ! 314: #endif ! 315: ! 316: /* Grab the region so we can find another board if autoIRQ fails. */ ! 317: request_region(ioaddr, SEEQ8005_IO_EXTENT,"seeq8005"); ! 318: ! 319: /* Initialize the device structure. */ ! 320: dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); ! 321: if (dev->priv == NULL) ! 322: return -ENOMEM; ! 323: memset(dev->priv, 0, sizeof(struct net_local)); ! 324: ! 325: dev->open = seeq8005_open; ! 326: dev->stop = seeq8005_close; ! 327: dev->hard_start_xmit = seeq8005_send_packet; ! 328: dev->get_stats = seeq8005_get_stats; ! 329: dev->set_multicast_list = &set_multicast_list; ! 330: ! 331: /* Fill in the fields of the device structure with ethernet values. */ ! 332: ether_setup(dev); ! 333: ! 334: dev->flags &= ~IFF_MULTICAST; ! 335: ! 336: return 0; ! 337: } ! 338: ! 339: ! 340: /* Open/initialize the board. This is called (in the current kernel) ! 341: sometime after booting when the 'ifconfig' program is run. ! 342: ! 343: This routine should set everything up anew at each open, even ! 344: registers that "should" only need to be set once at boot, so that ! 345: there is non-reboot way to recover if something goes wrong. ! 346: */ ! 347: static int ! 348: seeq8005_open(struct device *dev) ! 349: { ! 350: struct net_local *lp = (struct net_local *)dev->priv; ! 351: ! 352: { ! 353: int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", NULL); ! 354: if (irqval) { ! 355: printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, ! 356: dev->irq, irqval); ! 357: return EAGAIN; ! 358: } ! 359: } ! 360: irq2dev_map[dev->irq] = dev; ! 361: ! 362: /* Reset the hardware here. Don't forget to set the station address. */ ! 363: seeq8005_init(dev, 1); ! 364: ! 365: lp->open_time = jiffies; ! 366: ! 367: dev->tbusy = 0; ! 368: dev->interrupt = 0; ! 369: dev->start = 1; ! 370: return 0; ! 371: } ! 372: ! 373: static int ! 374: seeq8005_send_packet(struct sk_buff *skb, struct device *dev) ! 375: { ! 376: int ioaddr = dev->base_addr; ! 377: ! 378: if (dev->tbusy) { ! 379: /* If we get here, some higher level has decided we are broken. ! 380: There should really be a "kick me" function call instead. */ ! 381: int tickssofar = jiffies - dev->trans_start; ! 382: if (tickssofar < 5) ! 383: return 1; ! 384: printk("%s: transmit timed out, %s?\n", dev->name, ! 385: tx_done(dev) ? "IRQ conflict" : "network cable problem"); ! 386: /* Try to restart the adaptor. */ ! 387: seeq8005_init(dev, 1); ! 388: dev->tbusy=0; ! 389: dev->trans_start = jiffies; ! 390: } ! 391: ! 392: /* If some higher layer thinks we've missed an tx-done interrupt ! 393: we are passed NULL. Caution: dev_tint() handles the cli()/sti() ! 394: itself. */ ! 395: if (skb == NULL) { ! 396: dev_tint(dev); ! 397: return 0; ! 398: } ! 399: ! 400: /* Block a timer-based transmit from overlapping. This could better be ! 401: done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ ! 402: if (set_bit(0, (void*)&dev->tbusy) != 0) ! 403: printk("%s: Transmitter access conflict.\n", dev->name); ! 404: else { ! 405: short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; ! 406: unsigned char *buf = skb->data; ! 407: ! 408: hardware_send_packet(dev, buf, length); ! 409: dev->trans_start = jiffies; ! 410: } ! 411: dev_kfree_skb (skb, FREE_WRITE); ! 412: ! 413: /* You might need to clean up and record Tx statistics here. */ ! 414: ! 415: return 0; ! 416: } ! 417: ! 418: /* The typical workload of the driver: ! 419: Handle the network interface interrupts. */ ! 420: static void ! 421: seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs) ! 422: { ! 423: struct device *dev = (struct device *)(irq2dev_map[irq]); ! 424: struct net_local *lp; ! 425: int ioaddr, status, boguscount = 0; ! 426: ! 427: if (dev == NULL) { ! 428: printk ("net_interrupt(): irq %d for unknown device.\n", irq); ! 429: return; ! 430: } ! 431: ! 432: if (dev->interrupt) ! 433: printk ("%s: Re-entering the interrupt handler.\n", dev->name); ! 434: dev->interrupt = 1; ! 435: ! 436: ioaddr = dev->base_addr; ! 437: lp = (struct net_local *)dev->priv; ! 438: ! 439: status = inw(SEEQ_STATUS); ! 440: do { ! 441: if (net_debug >2) { ! 442: printk("%s: int, status=0x%04x\n",dev->name,status); ! 443: } ! 444: ! 445: if (status & SEEQSTAT_WINDOW_INT) { ! 446: outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); ! 447: if (net_debug) { ! 448: printk("%s: window int!\n",dev->name); ! 449: } ! 450: } ! 451: if (status & SEEQSTAT_TX_INT) { ! 452: outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); ! 453: lp->stats.tx_packets++; ! 454: dev->tbusy = 0; ! 455: mark_bh(NET_BH); /* Inform upper layers. */ ! 456: } ! 457: if (status & SEEQSTAT_RX_INT) { ! 458: /* Got a packet(s). */ ! 459: seeq8005_rx(dev); ! 460: } ! 461: status = inw(SEEQ_STATUS); ! 462: } while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ; ! 463: ! 464: if(net_debug>2) { ! 465: printk("%s: eoi\n",dev->name); ! 466: } ! 467: dev->interrupt = 0; ! 468: return; ! 469: } ! 470: ! 471: /* We have a good packet(s), get it/them out of the buffers. */ ! 472: static void ! 473: seeq8005_rx(struct device *dev) ! 474: { ! 475: struct net_local *lp = (struct net_local *)dev->priv; ! 476: int boguscount = 10; ! 477: int pkt_hdr; ! 478: int ioaddr = dev->base_addr; ! 479: ! 480: do { ! 481: int next_packet; ! 482: int pkt_len; ! 483: int i; ! 484: int status; ! 485: ! 486: status = inw(SEEQ_STATUS); ! 487: outw( lp->receive_ptr, SEEQ_DMAAR); ! 488: outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); ! 489: wait_for_buffer(dev); ! 490: next_packet = ntohs(inw(SEEQ_BUFFER)); ! 491: pkt_hdr = inw(SEEQ_BUFFER); ! 492: ! 493: if (net_debug>2) { ! 494: printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr); ! 495: } ! 496: ! 497: if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) { /* Read all the frames? */ ! 498: return; /* Done for now */ ! 499: } ! 500: ! 501: if ((pkt_hdr & SEEQPKTS_DONE)==0) ! 502: break; ! 503: ! 504: if (next_packet < lp->receive_ptr) { ! 505: pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4; ! 506: } else { ! 507: pkt_len = next_packet - lp->receive_ptr - 4; ! 508: } ! 509: ! 510: if (next_packet < ((DEFAULT_TEA+1)<<8)) { /* is the next_packet address sane? */ ! 511: printk("%s: recv packet ring corrupt, resetting board\n",dev->name); ! 512: seeq8005_init(dev,1); ! 513: return; ! 514: } ! 515: ! 516: lp->receive_ptr = next_packet; ! 517: ! 518: if (net_debug>2) { ! 519: printk("%s: recv len=0x%04x\n",dev->name,pkt_len); ! 520: } ! 521: ! 522: if (pkt_hdr & SEEQPKTS_ANY_ERROR) { /* There was an error. */ ! 523: lp->stats.rx_errors++; ! 524: if (pkt_hdr & SEEQPKTS_SHORT) lp->stats.rx_frame_errors++; ! 525: if (pkt_hdr & SEEQPKTS_DRIB) lp->stats.rx_frame_errors++; ! 526: if (pkt_hdr & SEEQPKTS_OVERSIZE) lp->stats.rx_over_errors++; ! 527: if (pkt_hdr & SEEQPKTS_CRC_ERR) lp->stats.rx_crc_errors++; ! 528: /* skip over this packet */ ! 529: outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); ! 530: outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA); ! 531: } else { ! 532: /* Malloc up new buffer. */ ! 533: struct sk_buff *skb; ! 534: unsigned char *buf; ! 535: ! 536: skb = dev_alloc_skb(pkt_len); ! 537: if (skb == NULL) { ! 538: printk("%s: Memory squeeze, dropping packet.\n", dev->name); ! 539: lp->stats.rx_dropped++; ! 540: break; ! 541: } ! 542: skb->dev = dev; ! 543: skb_reserve(skb, 2); /* align data on 16 byte */ ! 544: buf = skb_put(skb,pkt_len); ! 545: ! 546: insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1); ! 547: ! 548: if (net_debug>2) { ! 549: char * p = buf; ! 550: printk("%s: recv ",dev->name); ! 551: for(i=0;i<14;i++) { ! 552: printk("%02x ",*(p++)&0xff); ! 553: } ! 554: printk("\n"); ! 555: } ! 556: ! 557: skb->protocol=eth_type_trans(skb,dev); ! 558: netif_rx(skb); ! 559: lp->stats.rx_packets++; ! 560: } ! 561: } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN)); ! 562: ! 563: /* If any worth-while packets have been received, netif_rx() ! 564: has done a mark_bh(NET_BH) for us and will work on them ! 565: when we get to the bottom-half routine. */ ! 566: return; ! 567: } ! 568: ! 569: /* The inverse routine to net_open(). */ ! 570: static int ! 571: seeq8005_close(struct device *dev) ! 572: { ! 573: struct net_local *lp = (struct net_local *)dev->priv; ! 574: int ioaddr = dev->base_addr; ! 575: ! 576: lp->open_time = 0; ! 577: ! 578: dev->tbusy = 1; ! 579: dev->start = 0; ! 580: ! 581: /* Flush the Tx and disable Rx here. */ ! 582: outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD); ! 583: ! 584: free_irq(dev->irq, NULL); ! 585: ! 586: irq2dev_map[dev->irq] = 0; ! 587: ! 588: /* Update the statistics here. */ ! 589: ! 590: return 0; ! 591: ! 592: } ! 593: ! 594: /* Get the current statistics. This may be called with the card open or ! 595: closed. */ ! 596: static struct enet_statistics * ! 597: seeq8005_get_stats(struct device *dev) ! 598: { ! 599: struct net_local *lp = (struct net_local *)dev->priv; ! 600: ! 601: return &lp->stats; ! 602: } ! 603: ! 604: /* Set or clear the multicast filter for this adaptor. ! 605: num_addrs == -1 Promiscuous mode, receive all packets ! 606: num_addrs == 0 Normal mode, clear multicast list ! 607: num_addrs > 0 Multicast mode, receive normal and MC packets, and do ! 608: best-effort filtering. ! 609: */ ! 610: static void ! 611: set_multicast_list(struct device *dev) ! 612: { ! 613: /* ! 614: * I _could_ do up to 6 addresses here, but won't (yet?) ! 615: */ ! 616: ! 617: #if 0 ! 618: int ioaddr = dev->base_addr; ! 619: /* ! 620: * hmm, not even sure if my matching works _anyway_ - seem to be receiving ! 621: * _everything_ . . . ! 622: */ ! 623: ! 624: if (num_addrs) { /* Enable promiscuous mode */ ! 625: outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL, SEEQ_CFG1); ! 626: dev->flags|=IFF_PROMISC; ! 627: } else { /* Disable promiscuous mode, use normal mode */ ! 628: outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_BROAD, SEEQ_CFG1); ! 629: } ! 630: #endif ! 631: } ! 632: ! 633: void seeq8005_init(struct device *dev, int startp) ! 634: { ! 635: struct net_local *lp = (struct net_local *)dev->priv; ! 636: int ioaddr = dev->base_addr; ! 637: int i; ! 638: ! 639: outw(SEEQCFG2_RESET, SEEQ_CFG2); /* reset device */ ! 640: SLOW_DOWN_IO; /* have to wait 4us after a reset - should be fixed */ ! 641: SLOW_DOWN_IO; ! 642: SLOW_DOWN_IO; ! 643: SLOW_DOWN_IO; ! 644: ! 645: outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); ! 646: outw( 0, SEEQ_DMAAR); /* load start address into both low and high byte */ ! 647: /* wait_for_buffer(dev); */ /* I think that you only need a wait for memory buffer */ ! 648: outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1); ! 649: ! 650: for(i=0;i<6;i++) { /* set Station address */ ! 651: outb(dev->dev_addr[i], SEEQ_BUFFER); ! 652: SLOW_DOWN_IO; ! 653: } ! 654: ! 655: outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1); /* set xmit end area pointer to 16K */ ! 656: outb( DEFAULT_TEA, SEEQ_BUFFER); /* this gives us 16K of send buffer and 48K of recv buffer */ ! 657: ! 658: lp->receive_ptr = (DEFAULT_TEA+1)<<8; /* so we can find our packet_header */ ! 659: outw( lp->receive_ptr, SEEQ_RPR); /* Receive Pointer Register is set to recv buffer memory */ ! 660: ! 661: outw( 0x00ff, SEEQ_REA); /* Receive Area End */ ! 662: ! 663: if (net_debug>4) { ! 664: printk("%s: SA0 = ",dev->name); ! 665: ! 666: outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); ! 667: outw( 0, SEEQ_DMAAR); ! 668: outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1); ! 669: ! 670: for(i=0;i<6;i++) { ! 671: printk("%02x ",inb(SEEQ_BUFFER)); ! 672: } ! 673: printk("\n"); ! 674: } ! 675: ! 676: outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1); ! 677: outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2); ! 678: outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD); ! 679: ! 680: if (net_debug>4) { ! 681: int old_cfg1; ! 682: old_cfg1 = inw(SEEQ_CFG1); ! 683: printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS)); ! 684: printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1); ! 685: printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2)); ! 686: printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA)); ! 687: printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR)); ! 688: ! 689: } ! 690: } ! 691: ! 692: ! 693: void hardware_send_packet(struct device * dev, char *buf, int length) ! 694: { ! 695: int ioaddr = dev->base_addr; ! 696: int status = inw(SEEQ_STATUS); ! 697: int transmit_ptr = 0; ! 698: int tmp; ! 699: ! 700: if (net_debug>4) { ! 701: printk("%s: send 0x%04x\n",dev->name,length); ! 702: } ! 703: ! 704: /* Set FIFO to writemode and set packet-buffer address */ ! 705: outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD); ! 706: outw( transmit_ptr, SEEQ_DMAAR); ! 707: ! 708: /* output SEEQ Packet header barfage */ ! 709: outw( htons(length + 4), SEEQ_BUFFER); ! 710: outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER ); ! 711: ! 712: /* blat the buffer */ ! 713: outsw( SEEQ_BUFFER, buf, (length +1) >> 1); ! 714: /* paranoia !! */ ! 715: outw( 0, SEEQ_BUFFER); ! 716: outw( 0, SEEQ_BUFFER); ! 717: ! 718: /* set address of start of transmit chain */ ! 719: outw( transmit_ptr, SEEQ_TPR); ! 720: ! 721: /* drain FIFO */ ! 722: tmp = jiffies; ! 723: while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && (jiffies < tmp + HZ)) ! 724: mb(); ! 725: ! 726: /* doit ! */ ! 727: outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD); ! 728: ! 729: } ! 730: ! 731: ! 732: /* ! 733: * wait_for_buffer ! 734: * ! 735: * This routine waits for the SEEQ chip to assert that the FIFO is ready ! 736: * by checking for a window interrupt, and then clearing it ! 737: */ ! 738: inline void wait_for_buffer(struct device * dev) ! 739: { ! 740: int ioaddr = dev->base_addr; ! 741: int tmp; ! 742: int status; ! 743: ! 744: tmp = jiffies + HZ; ! 745: while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && jiffies < tmp) ! 746: mb(); ! 747: ! 748: if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT) ! 749: outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD); ! 750: } ! 751: ! 752: ! 753: /* ! 754: * Local variables: ! 755: * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c" ! 756: * version-control: t ! 757: * kept-new-versions: 5 ! 758: * tab-width: 4 ! 759: * End: ! 760: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.