|
|
1.1 ! root 1: /* yellowfin.c: A Packet Engines G-NIC ethernet driver for linux. */ ! 2: /* ! 3: Written 1997-1998 by Donald Becker. ! 4: ! 5: This software may be used and distributed according to the terms ! 6: of the GNU Public License, incorporated herein by reference. ! 7: ! 8: This driver is for the Packet Engines G-NIC PCI Gigabit Ethernet adapter. ! 9: It also supports the Symbios Logic version of the same chip core. ! 10: ! 11: The author may be reached as [email protected], or C/O ! 12: Center of Excellence in Space Data and Information Sciences ! 13: Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 ! 14: ! 15: Support and updates available at ! 16: http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html ! 17: */ ! 18: ! 19: static const char *version = "yellowfin.c:v0.99A 4/7/98 [email protected]\n"; ! 20: ! 21: /* A few user-configurable values. */ ! 22: ! 23: static int max_interrupt_work = 20; ! 24: static int min_pci_latency = 64; ! 25: static int mtu = 0; ! 26: #ifdef YF_PROTOTYPE /* Support for prototype hardware errata. */ ! 27: /* System-wide count of bogus-rx frames. */ ! 28: static int bogus_rx = 0; ! 29: static int dma_ctrl = 0x004A0263; /* Constrained by errata */ ! 30: static int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */ ! 31: #elif YF_NEW /* A future perfect board :->. */ ! 32: static int dma_ctrl = 0x00CAC277; /* Override when loading module! */ ! 33: static int fifo_cfg = 0x0028; ! 34: #else ! 35: static int dma_ctrl = 0x004A0263; /* Constrained by errata */ ! 36: static int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */ ! 37: #endif ! 38: ! 39: /* Set the copy breakpoint for the copy-only-tiny-frames scheme. ! 40: Setting to > 1518 effectively disables this feature. */ ! 41: static const int rx_copybreak = 100; ! 42: ! 43: /* Keep the ring sizes a power of two for efficiency. ! 44: Making the Tx ring too large decreases the effectiveness of channel ! 45: bonding and packet priority. ! 46: There are no ill effects from too-large receive rings. */ ! 47: #define TX_RING_SIZE 16 ! 48: #define RX_RING_SIZE 32 ! 49: ! 50: /* Operational parameters that usually are not changed. */ ! 51: /* Time in jiffies before concluding the transmitter is hung. */ ! 52: #define TX_TIMEOUT ((2000*HZ)/1000) ! 53: ! 54: #include <linux/config.h> ! 55: #ifdef MODULE ! 56: #ifdef MODVERSIONS ! 57: #include <linux/modversions.h> ! 58: #endif ! 59: #include <linux/module.h> ! 60: #include <linux/version.h> ! 61: #else ! 62: #define MOD_INC_USE_COUNT ! 63: #define MOD_DEC_USE_COUNT ! 64: #endif ! 65: ! 66: #include <linux/kernel.h> ! 67: #include <linux/sched.h> ! 68: #include <linux/string.h> ! 69: #include <linux/timer.h> ! 70: #include <linux/ptrace.h> ! 71: #include <linux/errno.h> ! 72: #include <linux/ioport.h> ! 73: #include <linux/malloc.h> ! 74: #include <linux/interrupt.h> ! 75: #include <linux/pci.h> ! 76: #include <linux/bios32.h> ! 77: #include <asm/processor.h> /* Processor type for cache alignment. */ ! 78: #include <asm/bitops.h> ! 79: #include <asm/io.h> ! 80: ! 81: #include <linux/netdevice.h> ! 82: #include <linux/etherdevice.h> ! 83: #include <linux/skbuff.h> ! 84: ! 85: /* Kernel compatibility defines, common to David Hind's PCMCIA package. ! 86: This is only in the support-all-kernels source code. */ ! 87: #include <linux/version.h> /* Evil, but neccessary */ ! 88: ! 89: #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x10300 ! 90: #define RUN_AT(x) (x) /* What to put in timer->expires. */ ! 91: #define DEV_ALLOC_SKB(len) alloc_skb(len, GFP_ATOMIC) ! 92: #define virt_to_bus(addr) ((unsigned long)addr) ! 93: #define bus_to_virt(addr) ((void*)addr) ! 94: ! 95: #else /* 1.3.0 and later */ ! 96: #define RUN_AT(x) (jiffies + (x)) ! 97: #define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2) ! 98: #endif ! 99: ! 100: #if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x10338 ! 101: #ifdef MODULE ! 102: #if !defined(CONFIG_MODVERSIONS) && !defined(__NO_VERSION__) ! 103: char kernel_version[] = UTS_RELEASE; ! 104: #endif ! 105: #else ! 106: #undef MOD_INC_USE_COUNT ! 107: #define MOD_INC_USE_COUNT ! 108: #undef MOD_DEC_USE_COUNT ! 109: #define MOD_DEC_USE_COUNT ! 110: #endif ! 111: #endif /* 1.3.38 */ ! 112: ! 113: #if (LINUX_VERSION_CODE >= 0x10344) ! 114: #define NEW_MULTICAST ! 115: #include <linux/delay.h> ! 116: #endif ! 117: #if (LINUX_VERSION_CODE >= 0x20100) ! 118: char kernel_version[] = UTS_RELEASE; ! 119: #endif ! 120: #ifdef SA_SHIRQ ! 121: #define IRQ(irq, dev_id, pt_regs) (irq, dev_id, pt_regs) ! 122: #else ! 123: #define IRQ(irq, dev_id, pt_regs) (irq, pt_regs) ! 124: #endif ! 125: #if (LINUX_VERSION_CODE < 0x20123) ! 126: #define test_and_set_bit(val, addr) set_bit(val, addr) ! 127: #endif ! 128: ! 129: static const char *card_name = "Yellowfin G-NIC Gbit Ethernet"; ! 130: ! 131: /* The PCI I/O space extent. */ ! 132: #define YELLOWFIN_TOTAL_SIZE 0x100 ! 133: ! 134: #ifdef HAVE_DEVLIST ! 135: struct netdev_entry yellowfin_drv = ! 136: {card_name, yellowfin_pci_probe, YELLOWFIN_TOTAL_SIZE, NULL}; ! 137: #endif ! 138: ! 139: #ifdef YELLOWFIN_DEBUG ! 140: int yellowfin_debug = YELLOWFIN_DEBUG; ! 141: #else ! 142: int yellowfin_debug = 1; ! 143: #endif ! 144: ! 145: /* ! 146: Theory of Operation ! 147: ! 148: I. Board Compatibility ! 149: ! 150: This device driver is designed for the Packet Engines "Yellowfin" Gigabit ! 151: Ethernet adapter. The only PCA currently supported is the G-NIC 64-bit ! 152: PCI card. ! 153: ! 154: II. Board-specific settings ! 155: ! 156: PCI bus devices are configured by the system at boot time, so no jumpers ! 157: need to be set on the board. The system BIOS preferably should assign the ! 158: PCI INTA signal to an otherwise unused system IRQ line. ! 159: Note: Kernel versions earlier than 1.3.73 do not support shared PCI ! 160: interrupt lines. ! 161: ! 162: III. Driver operation ! 163: ! 164: IIIa. Ring buffers ! 165: ! 166: The Yellowfin uses the Descriptor Based DMA Architecture specified by Apple. ! 167: This is a descriptor list scheme similar to that used by the EEPro100 and ! 168: Tulip. This driver uses two statically allocated fixed-size descriptor lists ! 169: formed into rings by a branch from the final descriptor to the beginning of ! 170: the list. The ring sizes are set at compile time by RX/TX_RING_SIZE. ! 171: ! 172: The driver allocates full frame size skbuffs for the Rx ring buffers at ! 173: open() time and passes the skb->data field to the Yellowfin as receive data ! 174: buffers. When an incoming frame is less than RX_COPYBREAK bytes long, ! 175: a fresh skbuff is allocated and the frame is copied to the new skbuff. ! 176: When the incoming frame is larger, the skbuff is passed directly up the ! 177: protocol stack and replaced by a newly allocated skbuff. ! 178: ! 179: The RX_COPYBREAK value is chosen to trade-off the memory wasted by ! 180: using a full-sized skbuff for small frames vs. the copying costs of larger ! 181: frames. For small frames the copying cost is negligible (esp. considering ! 182: that we are pre-loading the cache with immediately useful header ! 183: information). For large frames the copying cost is non-trivial, and the ! 184: larger copy might flush the cache of useful data. ! 185: ! 186: IIIC. Synchronization ! 187: ! 188: The driver runs as two independent, single-threaded flows of control. One ! 189: is the send-packet routine, which enforces single-threaded use by the ! 190: dev->tbusy flag. The other thread is the interrupt handler, which is single ! 191: threaded by the hardware and other software. ! 192: ! 193: The send packet thread has partial control over the Tx ring and 'dev->tbusy' ! 194: flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next ! 195: queue slot is empty, it clears the tbusy flag when finished otherwise it sets ! 196: the 'yp->tx_full' flag. ! 197: ! 198: The interrupt handler has exclusive control over the Rx ring and records stats ! 199: from the Tx ring. After reaping the stats, it marks the Tx queue entry as ! 200: empty by incrementing the dirty_tx mark. Iff the 'yp->tx_full' flag is set, it ! 201: clears both the tx_full and tbusy flags. ! 202: ! 203: IV. Notes ! 204: ! 205: Thanks to Kim Stearns of Packet Engines for providing a pair of G-NIC boards. ! 206: ! 207: IVb. References ! 208: ! 209: Yellowfin Engineering Design Specification, 4/23/97 Preliminary/Confidential ! 210: http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html ! 211: ! 212: IVc. Errata ! 213: ! 214: See Packet Engines confidential appendix. ! 215: ! 216: */ ! 217: ! 218: /* A few values that may be tweaked. */ ! 219: #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ ! 220: ! 221: #ifndef PCI_VENDOR_ID_PKT_ENG /* To be defined in linux/pci.h */ ! 222: #define PCI_VENDOR_ID_PKT_ENG 0x1000 /* Hmm, likely number.. */ ! 223: #define PCI_DEVICE_ID_YELLOWFIN 0x0702 ! 224: #endif ! 225: ! 226: /* The rest of these values should never change. */ ! 227: ! 228: static void yellowfin_timer(unsigned long data); ! 229: ! 230: /* Offsets to the Yellowfin registers. Various sizes and alignments. */ ! 231: enum yellowfin_offsets { ! 232: TxCtrl=0x00, TxStatus=0x04, TxPtr=0x0C, ! 233: TxIntrSel=0x10, TxBranchSel=0x14, TxWaitSel=0x18, ! 234: RxCtrl=0x40, RxStatus=0x44, RxPtr=0x4C, ! 235: RxIntrSel=0x50, RxBranchSel=0x54, RxWaitSel=0x58, ! 236: EventStatus=0x80, IntrEnb=0x82, IntrClear=0x84, IntrStatus=0x86, ! 237: ChipRev=0x8C, DMACtrl=0x90, Cnfg=0xA0, RxDepth=0xB8, FlowCtrl=0xBC, ! 238: AddrMode=0xD0, StnAddr=0xD2, HashTbl=0xD8, FIFOcfg=0xF8, ! 239: }; ! 240: ! 241: /* The Yellowfin Rx and Tx buffer descriptors. */ ! 242: struct yellowfin_desc { ! 243: u16 request_cnt; ! 244: u16 cmd; ! 245: u32 addr; ! 246: u32 branch_addr; ! 247: u16 result_cnt; ! 248: u16 status; ! 249: }; ! 250: ! 251: struct tx_status_words { ! 252: u16 tx_cnt; ! 253: u16 tx_errs; ! 254: u16 total_tx_cnt; ! 255: u16 paused; ! 256: }; ! 257: ! 258: /* Bits in yellowfin_desc.cmd */ ! 259: enum desc_cmd_bits { ! 260: CMD_TX_PKT=0x1000, CMD_RX_BUF=0x2000, CMD_TXSTATUS=0x3000, ! 261: CMD_NOP=0x6000, CMD_STOP=0x7000, ! 262: BRANCH_ALWAYS=0x0C, INTR_ALWAYS=0x30, WAIT_ALWAYS=0x03, ! 263: BRANCH_IFTRUE=0x04, ! 264: }; ! 265: ! 266: /* Bits in yellowfin_desc.status */ ! 267: enum desc_status_bits { RX_EOP=0x0040, }; ! 268: ! 269: /* Bits in the interrupt status/mask registers. */ ! 270: enum intr_status_bits { ! 271: IntrRxDone=0x01, IntrRxInvalid=0x02, IntrRxPCIFault=0x04,IntrRxPCIErr=0x08, ! 272: IntrTxDone=0x10, IntrTxInvalid=0x20, IntrTxPCIFault=0x40,IntrTxPCIErr=0x80, ! 273: IntrEarlyRx=0x100, IntrWakeup=0x200, }; ! 274: ! 275: struct yellowfin_private { ! 276: /* Descriptor rings first for alignment. Tx requires a second descriptor ! 277: for status. */ ! 278: struct yellowfin_desc rx_ring[RX_RING_SIZE]; ! 279: struct yellowfin_desc tx_ring[TX_RING_SIZE*2]; ! 280: const char *product_name; ! 281: struct device *next_module; ! 282: /* The saved address of a sent-in-place packet/buffer, for skfree(). */ ! 283: struct sk_buff* tx_skbuff[TX_RING_SIZE]; ! 284: struct tx_status_words tx_status[TX_RING_SIZE]; ! 285: /* The addresses of receive-in-place skbuffs. */ ! 286: struct sk_buff* rx_skbuff[RX_RING_SIZE]; ! 287: int chip_id; ! 288: struct enet_statistics stats; ! 289: struct timer_list timer; /* Media selection timer. */ ! 290: int in_interrupt; ! 291: unsigned int cur_rx, cur_tx; /* The next free ring entry */ ! 292: unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ ! 293: unsigned int tx_full:1; /* The Tx queue is full. */ ! 294: unsigned int full_duplex:1; /* Full-duplex operation requested. */ ! 295: unsigned int medialock:1; /* Do not sense media. */ ! 296: unsigned int default_port:4; /* Last dev->if_port value. */ ! 297: u32 pad[4]; /* Used for 32-byte alignment */ ! 298: }; ! 299: ! 300: #ifdef MODULE ! 301: /* Used to pass the media type, etc. */ ! 302: #define MAX_UNITS 8 /* More are supported, limit only on options */ ! 303: static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; ! 304: ! 305: #if LINUX_VERSION_CODE > 0x20115 ! 306: MODULE_AUTHOR("Donald Becker <[email protected]>"); ! 307: MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver"); ! 308: MODULE_PARM(max_interrupt_work, "i"); ! 309: MODULE_PARM(min_pci_latency, "i"); ! 310: MODULE_PARM(mtu, "i"); ! 311: MODULE_PARM(debug, "i"); ! 312: MODULE_PARM(rx_copybreak, "i"); ! 313: MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); ! 314: #endif ! 315: ! 316: #endif ! 317: ! 318: static struct device *yellowfin_probe1(struct device *dev, int ioaddr, int irq, ! 319: int chip_id, int options); ! 320: static int yellowfin_open(struct device *dev); ! 321: static void yellowfin_timer(unsigned long data); ! 322: static void yellowfin_tx_timeout(struct device *dev); ! 323: static void yellowfin_init_ring(struct device *dev); ! 324: static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev); ! 325: static int yellowfin_rx(struct device *dev); ! 326: static void yellowfin_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs); ! 327: static int yellowfin_close(struct device *dev); ! 328: static struct enet_statistics *yellowfin_get_stats(struct device *dev); ! 329: #ifdef NEW_MULTICAST ! 330: static void set_rx_mode(struct device *dev); ! 331: #else ! 332: static void set_rx_mode(struct device *dev, int num_addrs, void *addrs); ! 333: #endif ! 334: ! 335: ! 336: ! 337: #ifdef MODULE ! 338: /* A list of all installed Yellowfin devices, for removing the driver module. */ ! 339: static struct device *root_yellowfin_dev = NULL; ! 340: #endif ! 341: ! 342: int yellowfin_probe(struct device *dev) ! 343: { ! 344: int cards_found = 0; ! 345: static int pci_index = 0; /* Static, for multiple probe calls. */ ! 346: ! 347: /* Ideally we would detect all network cards in slot order. That would ! 348: be best done a central PCI probe dispatch, which wouldn't work ! 349: well with the current structure. So instead we detect just the ! 350: Yellowfin cards in slot order. */ ! 351: ! 352: if (pcibios_present()) { ! 353: unsigned char pci_bus, pci_device_fn; ! 354: ! 355: for (;pci_index < 0xff; pci_index++) { ! 356: u8 pci_irq_line, pci_latency; ! 357: u16 pci_command, vendor, device; ! 358: u32 pci_ioaddr, chip_idx = 0; ! 359: ! 360: #ifdef REVERSE_PROBE_ORDER ! 361: if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, ! 362: 0xfe - pci_index, ! 363: &pci_bus, &pci_device_fn) ! 364: != PCIBIOS_SUCCESSFUL) ! 365: continue; ! 366: #else ! 367: if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, ! 368: pci_index, ! 369: &pci_bus, &pci_device_fn) ! 370: != PCIBIOS_SUCCESSFUL) ! 371: break; ! 372: #endif ! 373: pcibios_read_config_word(pci_bus, pci_device_fn, ! 374: PCI_VENDOR_ID, &vendor); ! 375: pcibios_read_config_word(pci_bus, pci_device_fn, ! 376: PCI_DEVICE_ID, &device); ! 377: pcibios_read_config_byte(pci_bus, pci_device_fn, ! 378: PCI_INTERRUPT_LINE, &pci_irq_line); ! 379: pcibios_read_config_dword(pci_bus, pci_device_fn, ! 380: PCI_BASE_ADDRESS_0, &pci_ioaddr); ! 381: /* Remove I/O space marker in bit 0. */ ! 382: pci_ioaddr &= ~3; ! 383: ! 384: if (vendor != PCI_VENDOR_ID_PKT_ENG) ! 385: continue; ! 386: ! 387: if (device != PCI_DEVICE_ID_YELLOWFIN) ! 388: continue; ! 389: ! 390: if (yellowfin_debug > 2) ! 391: printk("Found Packet Engines Yellowfin G-NIC at I/O %#x, IRQ %d.\n", ! 392: pci_ioaddr, pci_irq_line); ! 393: ! 394: if (check_region(pci_ioaddr, YELLOWFIN_TOTAL_SIZE)) ! 395: continue; ! 396: ! 397: #ifdef MODULE ! 398: dev = yellowfin_probe1(dev, pci_ioaddr, pci_irq_line, chip_idx, ! 399: cards_found < MAX_UNITS ? options[cards_found] : 0); ! 400: #else ! 401: dev = yellowfin_probe1(dev, pci_ioaddr, pci_irq_line, chip_idx, ! 402: dev ? dev->mem_start : 0); ! 403: #endif ! 404: ! 405: if (dev) { ! 406: /* Get and check the bus-master and latency values. */ ! 407: pcibios_read_config_word(pci_bus, pci_device_fn, ! 408: PCI_COMMAND, &pci_command); ! 409: if ( ! (pci_command & PCI_COMMAND_MASTER)) { ! 410: printk(" PCI Master Bit has not been set! Setting...\n"); ! 411: pci_command |= PCI_COMMAND_MASTER; ! 412: pcibios_write_config_word(pci_bus, pci_device_fn, ! 413: PCI_COMMAND, pci_command); ! 414: } ! 415: pcibios_read_config_byte(pci_bus, pci_device_fn, ! 416: PCI_LATENCY_TIMER, &pci_latency); ! 417: if (pci_latency < min_pci_latency) { ! 418: printk(" PCI latency timer (CFLT) is unreasonably low at %d." ! 419: " Setting to %d clocks.\n", ! 420: pci_latency, min_pci_latency); ! 421: pcibios_write_config_byte(pci_bus, pci_device_fn, ! 422: PCI_LATENCY_TIMER, min_pci_latency); ! 423: } else if (yellowfin_debug > 1) ! 424: printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency); ! 425: dev = 0; ! 426: cards_found++; ! 427: } ! 428: } ! 429: } ! 430: ! 431: #if defined (MODULE) ! 432: return cards_found; ! 433: #else ! 434: return 0; ! 435: #endif ! 436: } ! 437: ! 438: static struct device *yellowfin_probe1(struct device *dev, int ioaddr, int irq, ! 439: int chip_id, int options) ! 440: { ! 441: static int did_version = 0; /* Already printed version info. */ ! 442: struct yellowfin_private *yp; ! 443: int i; ! 444: ! 445: if (yellowfin_debug > 0 && did_version++ == 0) ! 446: printk(version); ! 447: ! 448: dev = init_etherdev(dev, sizeof(struct yellowfin_private)); ! 449: ! 450: printk("%s: P-E Yellowfin type %8x at %#3x, ", ! 451: dev->name, inl(ioaddr + ChipRev), ioaddr); ! 452: ! 453: for (i = 0; i < 5; i++) ! 454: printk("%2.2x:", inb(ioaddr + StnAddr + i)); ! 455: printk("%2.2x, IRQ %d.\n", inb(ioaddr + StnAddr + i), irq); ! 456: for (i = 0; i < 6; i++) ! 457: dev->dev_addr[i] = inb(ioaddr + StnAddr + i); ! 458: ! 459: /* Reset the chip. */ ! 460: outl(0x80000000, ioaddr + DMACtrl); ! 461: ! 462: ! 463: /* We do a request_region() only to register /proc/ioports info. */ ! 464: request_region(ioaddr, YELLOWFIN_TOTAL_SIZE, card_name); ! 465: ! 466: dev->base_addr = ioaddr; ! 467: dev->irq = irq; ! 468: ! 469: /* Make certain the descriptor lists are aligned. */ ! 470: yp = (void *)(((long)kmalloc(sizeof(*yp), GFP_KERNEL) + 31) & ~31); ! 471: memset(yp, 0, sizeof(*yp)); ! 472: dev->priv = yp; ! 473: ! 474: #ifdef MODULE ! 475: yp->next_module = root_yellowfin_dev; ! 476: root_yellowfin_dev = dev; ! 477: #endif ! 478: ! 479: yp->chip_id = chip_id; ! 480: ! 481: yp->full_duplex = 1; ! 482: #ifdef YELLOWFIN_DEFAULT_MEDIA ! 483: yp->default_port = YELLOWFIN_DEFAULT_MEDIA; ! 484: #endif ! 485: #ifdef YELLOWFIN_NO_MEDIA_SWITCH ! 486: yp->medialock = 1; ! 487: #endif ! 488: ! 489: /* The lower four bits are the media type. */ ! 490: if (options > 0) { ! 491: yp->full_duplex = (options & 16) ? 1 : 0; ! 492: yp->default_port = options & 15; ! 493: if (yp->default_port) ! 494: yp->medialock = 1; ! 495: } ! 496: ! 497: /* The Yellowfin-specific entries in the device structure. */ ! 498: dev->open = &yellowfin_open; ! 499: dev->hard_start_xmit = &yellowfin_start_xmit; ! 500: dev->stop = &yellowfin_close; ! 501: dev->get_stats = &yellowfin_get_stats; ! 502: dev->set_multicast_list = &set_rx_mode; ! 503: if (mtu) ! 504: dev->mtu = mtu; ! 505: ! 506: /* todo: Reset the xcvr interface and turn on heartbeat. */ ! 507: ! 508: return dev; ! 509: } ! 510: ! 511: ! 512: static int ! 513: yellowfin_open(struct device *dev) ! 514: { ! 515: struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; ! 516: int ioaddr = dev->base_addr; ! 517: ! 518: /* Reset the chip. */ ! 519: outl(0x80000000, ioaddr + DMACtrl); ! 520: ! 521: #ifdef SA_SHIRQ ! 522: if (request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ, ! 523: card_name, dev)) { ! 524: return -EAGAIN; ! 525: } ! 526: #else ! 527: if (irq2dev_map[dev->irq] != NULL ! 528: || (irq2dev_map[dev->irq] = dev) == NULL ! 529: || dev->irq == 0 ! 530: || request_irq(dev->irq, &yellowfin_interrupt, 0, card_name)) { ! 531: return -EAGAIN; ! 532: } ! 533: #endif ! 534: ! 535: if (yellowfin_debug > 1) ! 536: printk("%s: yellowfin_open() irq %d.\n", dev->name, dev->irq); ! 537: ! 538: MOD_INC_USE_COUNT; ! 539: ! 540: yellowfin_init_ring(dev); ! 541: ! 542: outl(virt_to_bus(yp->rx_ring), ioaddr + RxPtr); ! 543: outl(virt_to_bus(yp->tx_ring), ioaddr + TxPtr); ! 544: ! 545: /* Set up various condition 'select' registers. ! 546: There are no options here. */ ! 547: outl(0x00800080, ioaddr + TxIntrSel); /* Interrupt on Tx abort */ ! 548: outl(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */ ! 549: outl(0x00400040, ioaddr + TxWaitSel); /* Wait on Tx status */ ! 550: outl(0x00400040, ioaddr + RxIntrSel); /* Interrupt on Rx done */ ! 551: outl(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */ ! 552: outl(0x00400040, ioaddr + RxWaitSel); /* Wait on Rx done */ ! 553: ! 554: /* Initialize other registers: with so many this eventually this will ! 555: converted to an offset/value list. */ ! 556: outl(dma_ctrl, ioaddr + DMACtrl); ! 557: outw(fifo_cfg, ioaddr + FIFOcfg); ! 558: /* Enable automatic generation of flow control frames, period 0xffff. */ ! 559: outl(0x0030FFFF, ioaddr + FlowCtrl); ! 560: ! 561: if (dev->if_port == 0) ! 562: dev->if_port = yp->default_port; ! 563: ! 564: dev->tbusy = 0; ! 565: dev->interrupt = 0; ! 566: yp->in_interrupt = 0; ! 567: ! 568: /* We are always in full-duplex mode with the current chip! */ ! 569: yp->full_duplex = 1; ! 570: ! 571: /* Setting the Rx mode will start the Rx process. */ ! 572: outw(0x01CD | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); ! 573: #ifdef NEW_MULTICAST ! 574: set_rx_mode(dev); ! 575: #else ! 576: set_rx_mode(dev, 0, 0); ! 577: #endif ! 578: ! 579: dev->start = 1; ! 580: ! 581: /* Enable interrupts by setting the interrupt mask. */ ! 582: outw(0x81ff, ioaddr + IntrEnb); /* See enum intr_status_bits */ ! 583: outw(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */ ! 584: outl(0x80008000, ioaddr + RxCtrl); /* Start Rx and Tx channels. */ ! 585: outl(0x80008000, ioaddr + TxCtrl); ! 586: ! 587: if (yellowfin_debug > 2) { ! 588: printk("%s: Done yellowfin_open().\n", ! 589: dev->name); ! 590: } ! 591: /* Set the timer to check for link beat. */ ! 592: init_timer(&yp->timer); ! 593: yp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */ ! 594: yp->timer.data = (unsigned long)dev; ! 595: yp->timer.function = &yellowfin_timer; /* timer handler */ ! 596: add_timer(&yp->timer); ! 597: ! 598: return 0; ! 599: } ! 600: ! 601: static void yellowfin_timer(unsigned long data) ! 602: { ! 603: struct device *dev = (struct device *)data; ! 604: struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; ! 605: int ioaddr = dev->base_addr; ! 606: int next_tick = 0; ! 607: ! 608: if (yellowfin_debug > 3) { ! 609: printk("%s: Yellowfin timer tick, status %8.8x.\n", ! 610: dev->name, inl(ioaddr + IntrStatus)); ! 611: } ! 612: if (next_tick) { ! 613: yp->timer.expires = RUN_AT(next_tick); ! 614: add_timer(&yp->timer); ! 615: } ! 616: } ! 617: ! 618: static void yellowfin_tx_timeout(struct device *dev) ! 619: { ! 620: struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; ! 621: int ioaddr = dev->base_addr; ! 622: ! 623: printk("%s: Yellowfin transmit timed out, status %8.8x, resetting...\n", ! 624: dev->name, inl(ioaddr)); ! 625: ! 626: #ifndef __alpha__ ! 627: { ! 628: int i; ! 629: printk(" Rx ring %8.8x: ", (int)yp->rx_ring); ! 630: for (i = 0; i < RX_RING_SIZE; i++) ! 631: printk(" %8.8x", (unsigned int)yp->rx_ring[i].status); ! 632: printk("\n Tx ring %8.8x: ", (int)yp->tx_ring); ! 633: for (i = 0; i < TX_RING_SIZE; i++) ! 634: printk(" %4.4x /%4.4x", yp->tx_status[i].tx_errs, yp->tx_ring[i].status); ! 635: printk("\n"); ! 636: } ! 637: #endif ! 638: ! 639: /* Perhaps we should reinitialize the hardware here. */ ! 640: dev->if_port = 0; ! 641: /* Stop and restart the chip's Tx processes . */ ! 642: ! 643: /* Trigger an immediate transmit demand. */ ! 644: ! 645: dev->trans_start = jiffies; ! 646: yp->stats.tx_errors++; ! 647: return; ! 648: } ! 649: ! 650: ! 651: /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ ! 652: static void ! 653: yellowfin_init_ring(struct device *dev) ! 654: { ! 655: struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; ! 656: int i; ! 657: ! 658: yp->tx_full = 0; ! 659: yp->cur_rx = yp->cur_tx = 0; ! 660: yp->dirty_rx = yp->dirty_tx = 0; ! 661: ! 662: for (i = 0; i < RX_RING_SIZE; i++) { ! 663: struct sk_buff *skb; ! 664: int pkt_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); ! 665: ! 666: yp->rx_ring[i].request_cnt = pkt_buf_sz; ! 667: yp->rx_ring[i].cmd = CMD_RX_BUF | INTR_ALWAYS; ! 668: ! 669: skb = DEV_ALLOC_SKB(pkt_buf_sz); ! 670: skb_reserve(skb, 2); /* 16 byte align the IP header. */ ! 671: yp->rx_skbuff[i] = skb; ! 672: if (skb == NULL) ! 673: break; /* Bad news! */ ! 674: skb->dev = dev; /* Mark as being used by this device. */ ! 675: #if LINUX_VERSION_CODE > 0x10300 ! 676: yp->rx_ring[i].addr = virt_to_bus(skb->tail); ! 677: #else ! 678: yp->rx_ring[i].addr = virt_to_bus(skb->data); ! 679: #endif ! 680: yp->rx_ring[i].branch_addr = virt_to_bus(&yp->rx_ring[i+1]); ! 681: } ! 682: /* Mark the last entry as wrapping the ring. */ ! 683: yp->rx_ring[i-1].cmd = CMD_RX_BUF | INTR_ALWAYS | BRANCH_ALWAYS; ! 684: yp->rx_ring[i-1].branch_addr = virt_to_bus(&yp->rx_ring[0]); ! 685: ! 686: /*#define NO_TXSTATS*/ ! 687: #ifdef NO_TXSTATS ! 688: /* In this mode the Tx ring needs only a single descriptor. */ ! 689: for (i = 0; i < TX_RING_SIZE; i++) { ! 690: yp->tx_skbuff[i] = 0; ! 691: yp->tx_ring[i].cmd = CMD_STOP; ! 692: yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[i+1]); ! 693: } ! 694: yp->tx_ring[--i].cmd = CMD_STOP | BRANCH_ALWAYS; /* Wrap ring */ ! 695: yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[0]); ! 696: #else ! 697: /* Tx ring needs a pair of descriptors, the second for the status. */ ! 698: for (i = 0; i < TX_RING_SIZE*2; i++) { ! 699: yp->tx_skbuff[i/2] = 0; ! 700: yp->tx_ring[i].cmd = CMD_STOP; /* Branch on Tx error. */ ! 701: yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[i+1]); ! 702: i++; ! 703: yp->tx_ring[i].cmd = CMD_TXSTATUS; /* Interrupt, no wait. */ ! 704: yp->tx_ring[i].request_cnt = sizeof(yp->tx_status[i]); ! 705: yp->tx_ring[i].addr = virt_to_bus(&yp->tx_status[i/2]); ! 706: yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[i+1]); ! 707: } ! 708: /* Wrap ring */ ! 709: yp->tx_ring[--i].cmd = CMD_TXSTATUS | BRANCH_ALWAYS | INTR_ALWAYS; ! 710: yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[0]); ! 711: #endif ! 712: } ! 713: ! 714: static int ! 715: yellowfin_start_xmit(struct sk_buff *skb, struct device *dev) ! 716: { ! 717: struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; ! 718: unsigned entry; ! 719: ! 720: /* Block a timer-based transmit from overlapping. This could better be ! 721: done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ ! 722: if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { ! 723: if (jiffies - dev->trans_start < TX_TIMEOUT) ! 724: return 1; ! 725: yellowfin_tx_timeout(dev); ! 726: return 1; ! 727: } ! 728: ! 729: /* Caution: the write order is important here, set the base address ! 730: with the "ownership" bits last. */ ! 731: ! 732: /* Calculate the next Tx descriptor entry. */ ! 733: entry = yp->cur_tx % TX_RING_SIZE; ! 734: ! 735: yp->tx_skbuff[entry] = skb; ! 736: ! 737: #ifdef NO_TXSTATS ! 738: yp->tx_ring[entry].request_cnt = skb->len; ! 739: yp->tx_ring[entry].addr = virt_to_bus(skb->data); ! 740: yp->tx_ring[entry].status = 0; ! 741: if (entry >= TX_RING_SIZE-1) { ! 742: yp->tx_ring[0].cmd = CMD_STOP; /* New stop command. */ ! 743: yp->tx_ring[TX_RING_SIZE-1].cmd = CMD_TX_PKT | BRANCH_ALWAYS; ! 744: } else { ! 745: yp->tx_ring[entry+1].cmd = CMD_STOP; /* New stop command. */ ! 746: yp->tx_ring[entry].cmd = CMD_TX_PKT | BRANCH_IFTRUE; ! 747: } ! 748: yp->cur_tx++; ! 749: #else ! 750: yp->tx_ring[entry<<1].request_cnt = skb->len; ! 751: yp->tx_ring[entry<<1].addr = virt_to_bus(skb->data); ! 752: /* The input_last (status-write) command is constant, but we must rewrite ! 753: the subsequent 'stop' command. */ ! 754: ! 755: yp->cur_tx++; ! 756: { ! 757: unsigned next_entry = yp->cur_tx % TX_RING_SIZE; ! 758: yp->tx_ring[next_entry<<1].cmd = CMD_STOP; ! 759: } ! 760: /* Final step -- overwrite the old 'stop' command. */ ! 761: ! 762: yp->tx_ring[entry<<1].cmd = ! 763: (entry % 6) == 0 ? CMD_TX_PKT | INTR_ALWAYS | BRANCH_IFTRUE : ! 764: CMD_TX_PKT | BRANCH_IFTRUE; ! 765: #endif ! 766: ! 767: /* Todo: explicitly flush cache lines here. */ ! 768: ! 769: /* Wake the potentially-idle transmit channel. */ ! 770: outl(0x10001000, dev->base_addr + TxCtrl); ! 771: ! 772: if (yp->cur_tx - yp->dirty_tx < TX_RING_SIZE - 1) ! 773: clear_bit(0, (void*)&dev->tbusy); /* Typical path */ ! 774: else ! 775: yp->tx_full = 1; ! 776: dev->trans_start = jiffies; ! 777: ! 778: if (yellowfin_debug > 4) { ! 779: printk("%s: Yellowfin transmit frame #%d queued in slot %d.\n", ! 780: dev->name, yp->cur_tx, entry); ! 781: } ! 782: return 0; ! 783: } ! 784: ! 785: /* The interrupt handler does all of the Rx thread work and cleans up ! 786: after the Tx thread. */ ! 787: static void yellowfin_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs) ! 788: { ! 789: #ifdef SA_SHIRQ /* Use the now-standard shared IRQ implementation. */ ! 790: struct device *dev = (struct device *)dev_instance; ! 791: #else ! 792: struct device *dev = (struct device *)(irq2dev_map[irq]); ! 793: #endif ! 794: ! 795: struct yellowfin_private *lp; ! 796: int ioaddr, boguscnt = max_interrupt_work; ! 797: ! 798: if (dev == NULL) { ! 799: printk ("yellowfin_interrupt(): irq %d for unknown device.\n", irq); ! 800: return; ! 801: } ! 802: ! 803: ioaddr = dev->base_addr; ! 804: lp = (struct yellowfin_private *)dev->priv; ! 805: if (test_and_set_bit(0, (void*)&lp->in_interrupt)) { ! 806: dev->interrupt = 1; ! 807: printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name); ! 808: return; ! 809: } ! 810: ! 811: do { ! 812: u16 intr_status = inw(ioaddr + IntrClear); ! 813: unsigned dirty_tx = lp->dirty_tx; ! 814: ! 815: if (yellowfin_debug > 4) ! 816: printk("%s: Yellowfin interrupt, status %4.4x.\n", ! 817: dev->name, intr_status); ! 818: ! 819: if (intr_status == 0) ! 820: break; ! 821: ! 822: if (intr_status & (IntrRxDone | IntrEarlyRx)) ! 823: yellowfin_rx(dev); ! 824: ! 825: #ifdef NO_TXSTATS ! 826: for (; lp->cur_tx - dirty_tx > 0; dirty_tx++) { ! 827: int entry = dirty_tx % TX_RING_SIZE; ! 828: if (lp->tx_ring[entry].status == 0) ! 829: break; ! 830: /* Free the original skb. */ ! 831: dev_kfree_skb(lp->tx_skbuff[entry], FREE_WRITE); ! 832: lp->tx_skbuff[entry] = 0; ! 833: lp->stats.tx_packets++; ! 834: } ! 835: if (lp->tx_full && dev->tbusy ! 836: && lp->cur_tx - dirty_tx < TX_RING_SIZE - 4) { ! 837: /* The ring is no longer full, clear tbusy. */ ! 838: lp->tx_full = 0; ! 839: clear_bit(0, (void*)&dev->tbusy); ! 840: mark_bh(NET_BH); ! 841: } ! 842: lp->dirty_tx = dirty_tx; ! 843: #else ! 844: if (intr_status & IntrTxDone ! 845: || lp->tx_status[dirty_tx % TX_RING_SIZE].tx_errs) { ! 846: ! 847: for (dirty_tx = lp->dirty_tx; lp->cur_tx - dirty_tx > 0; ! 848: dirty_tx++) { ! 849: /* Todo: optimize this. */ ! 850: int entry = dirty_tx % TX_RING_SIZE; ! 851: u16 tx_errs = lp->tx_status[entry].tx_errs; ! 852: ! 853: if (tx_errs == 0) ! 854: break; /* It still hasn't been Txed */ ! 855: if (tx_errs & 0xF8100000) { ! 856: /* There was an major error, log it. */ ! 857: #ifndef final_version ! 858: if (yellowfin_debug > 1) ! 859: printk("%s: Transmit error, Tx status %4.4x.\n", ! 860: dev->name, tx_errs); ! 861: #endif ! 862: lp->stats.tx_errors++; ! 863: if (tx_errs & 0xF800) lp->stats.tx_aborted_errors++; ! 864: if (tx_errs & 0x0800) lp->stats.tx_carrier_errors++; ! 865: if (tx_errs & 0x2000) lp->stats.tx_window_errors++; ! 866: if (tx_errs & 0x8000) lp->stats.tx_fifo_errors++; ! 867: #ifdef ETHER_STATS ! 868: if (tx_errs & 0x1000) lp->stats.collisions16++; ! 869: #endif ! 870: } else { ! 871: #ifdef ETHER_STATS ! 872: if (status & 0x0400) lp->stats.tx_deferred++; ! 873: #endif ! 874: lp->stats.collisions += tx_errs & 15; ! 875: lp->stats.tx_packets++; ! 876: } ! 877: ! 878: /* Free the original skb. */ ! 879: dev_kfree_skb(lp->tx_skbuff[entry], FREE_WRITE); ! 880: lp->tx_skbuff[entry] = 0; ! 881: /* Mark status as empty. */ ! 882: lp->tx_status[entry].tx_errs = 0; ! 883: } ! 884: ! 885: #ifndef final_version ! 886: if (lp->cur_tx - dirty_tx > TX_RING_SIZE) { ! 887: printk("%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n", ! 888: dev->name, dirty_tx, lp->cur_tx, lp->tx_full); ! 889: dirty_tx += TX_RING_SIZE; ! 890: } ! 891: #endif ! 892: ! 893: if (lp->tx_full && dev->tbusy ! 894: && lp->cur_tx - dirty_tx < TX_RING_SIZE - 2) { ! 895: /* The ring is no longer full, clear tbusy. */ ! 896: lp->tx_full = 0; ! 897: clear_bit(0, (void*)&dev->tbusy); ! 898: mark_bh(NET_BH); ! 899: } ! 900: ! 901: lp->dirty_tx = dirty_tx; ! 902: } ! 903: #endif ! 904: ! 905: /* Log errors and other events. */ ! 906: if (intr_status & 0x2ee) { /* Abnormal error summary. */ ! 907: printk("%s: Something Wicked happened! %4.4x.\n", ! 908: dev->name, intr_status); ! 909: /* Hmmmmm, it's not clear what to do here. */ ! 910: if (intr_status & (IntrTxPCIErr | IntrTxPCIFault)) ! 911: lp->stats.tx_errors++; ! 912: if (intr_status & (IntrRxPCIErr | IntrRxPCIFault)) ! 913: lp->stats.rx_errors++; ! 914: } ! 915: if (--boguscnt < 0) { ! 916: printk("%s: Too much work at interrupt, status=0x%4.4x.\n", ! 917: dev->name, intr_status); ! 918: break; ! 919: } ! 920: } while (1); ! 921: ! 922: if (yellowfin_debug > 3) ! 923: printk("%s: exiting interrupt, status=%#4.4x.\n", ! 924: dev->name, inw(ioaddr + IntrStatus)); ! 925: ! 926: /* Code that should never be run! Perhaps remove after testing.. */ ! 927: { ! 928: static int stopit = 10; ! 929: if (dev->start == 0 && --stopit < 0) { ! 930: printk("%s: Emergency stop, looping startup interrupt.\n", ! 931: dev->name); ! 932: #ifdef SA_SHIRQ ! 933: free_irq(irq, dev); ! 934: #else ! 935: free_irq(irq); ! 936: #endif ! 937: } ! 938: } ! 939: ! 940: dev->interrupt = 0; ! 941: clear_bit(0, (void*)&lp->in_interrupt); ! 942: return; ! 943: } ! 944: ! 945: /* This routine is logically part of the interrupt handler, but separated ! 946: for clarity and better register allocation. */ ! 947: static int ! 948: yellowfin_rx(struct device *dev) ! 949: { ! 950: struct yellowfin_private *lp = (struct yellowfin_private *)dev->priv; ! 951: struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; ! 952: int entry = lp->cur_rx % RX_RING_SIZE; ! 953: int boguscnt = 20; ! 954: ! 955: if (yellowfin_debug > 4) { ! 956: printk(" In yellowfin_rx(), entry %d status %4.4x.\n", entry, ! 957: yp->rx_ring[entry].status); ! 958: printk(" #%d desc. %4.4x %4.4x %8.8x %4.4x %4.4x.\n", ! 959: entry, yp->rx_ring[entry].cmd, ! 960: yp->rx_ring[entry].request_cnt, yp->rx_ring[entry].addr, ! 961: yp->rx_ring[entry].result_cnt, yp->rx_ring[entry].status); ! 962: } ! 963: ! 964: ! 965: /* If EOP is set on the next entry, it's a new packet. Send it up. */ ! 966: while (yp->rx_ring[entry].status) { ! 967: /* Todo: optimize this mess. */ ! 968: u16 desc_status = yp->rx_ring[entry].status; ! 969: struct yellowfin_desc *desc = &lp->rx_ring[entry]; ! 970: int frm_size = desc->request_cnt - desc->result_cnt; ! 971: u8 *buf_addr = bus_to_virt(lp->rx_ring[entry].addr); ! 972: s16 frame_status = *(s16*)&(buf_addr[frm_size - 2]); ! 973: ! 974: if (yellowfin_debug > 4) ! 975: printk(" yellowfin_rx() status was %4.4x.\n", frame_status); ! 976: if (--boguscnt < 0) ! 977: break; ! 978: if ( ! (desc_status & RX_EOP)) { ! 979: printk("%s: Oversized Ethernet frame spanned multiple buffers," ! 980: " status %4.4x!\n", dev->name, desc_status); ! 981: lp->stats.rx_length_errors++; ! 982: } else if (frame_status & 0x0038) { ! 983: /* There was a error. */ ! 984: if (yellowfin_debug > 3) ! 985: printk(" yellowfin_rx() Rx error was %4.4x.\n", frame_status); ! 986: lp->stats.rx_errors++; ! 987: if (frame_status & 0x0060) lp->stats.rx_length_errors++; ! 988: if (frame_status & 0x0008) lp->stats.rx_frame_errors++; ! 989: if (frame_status & 0x0010) lp->stats.rx_crc_errors++; ! 990: if (frame_status < 0) lp->stats.rx_dropped++; ! 991: #ifdef YF_PROTOTYPE /* Support for prototype hardware errata. */ ! 992: } else if (memcmp(bus_to_virt(lp->rx_ring[entry].addr), ! 993: dev->dev_addr, 6) != 0 ! 994: && memcmp(bus_to_virt(lp->rx_ring[entry].addr), ! 995: "\377\377\377\377\377\377", 6) != 0) { ! 996: printk("%s: Bad frame to %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", ! 997: dev->name, ! 998: ((char *)bus_to_virt(lp->rx_ring[entry].addr))[0], ! 999: ((char *)bus_to_virt(lp->rx_ring[entry].addr))[1], ! 1000: ((char *)bus_to_virt(lp->rx_ring[entry].addr))[2], ! 1001: ((char *)bus_to_virt(lp->rx_ring[entry].addr))[3], ! 1002: ((char *)bus_to_virt(lp->rx_ring[entry].addr))[4], ! 1003: ((char *)bus_to_virt(lp->rx_ring[entry].addr))[5]); ! 1004: bogus_rx++; ! 1005: #endif ! 1006: } else { ! 1007: u8 bogus_cnt = buf_addr[frm_size - 8]; ! 1008: int pkt_len = frm_size - 8 - bogus_cnt; ! 1009: struct sk_buff *skb; ! 1010: int rx_in_place = 0; ! 1011: ! 1012: /* Check if the packet is long enough to just accept without ! 1013: copying to a properly sized skbuff. */ ! 1014: if (pkt_len > rx_copybreak) { ! 1015: struct sk_buff *newskb; ! 1016: char *temp; ! 1017: ! 1018: /* Get a fresh skbuff to replace the filled one. */ ! 1019: newskb = DEV_ALLOC_SKB(dev->mtu <= 1500 ? PKT_BUF_SZ ! 1020: : dev->mtu + 32); ! 1021: if (newskb == NULL) { ! 1022: skb = 0; /* No memory, drop the packet. */ ! 1023: goto memory_squeeze; ! 1024: } ! 1025: /* Pass up the skb already on the Rx ring. */ ! 1026: skb = lp->rx_skbuff[entry]; ! 1027: temp = skb_put(skb, pkt_len); ! 1028: if (bus_to_virt(lp->rx_ring[entry].addr) != temp) ! 1029: printk("%s: Warning -- the skbuff addresses do not match" ! 1030: " in yellowfin_rx: %p vs. %p / %p.\n", dev->name, ! 1031: bus_to_virt(lp->rx_ring[entry].addr), ! 1032: skb->head, temp); ! 1033: rx_in_place = 1; ! 1034: lp->rx_skbuff[entry] = newskb; ! 1035: newskb->dev = dev; ! 1036: skb_reserve(newskb, 2); /* 16 byte align IP header */ ! 1037: lp->rx_ring[entry].addr = virt_to_bus(newskb->tail); ! 1038: } else ! 1039: skb = DEV_ALLOC_SKB(pkt_len + 2); ! 1040: memory_squeeze: ! 1041: if (skb == NULL) { ! 1042: printk("%s: Memory squeeze, deferring packet.\n", dev->name); ! 1043: /* todo: Check that at least two ring entries are free. ! 1044: If not, free one and mark stats->rx_dropped++. */ ! 1045: break; ! 1046: } ! 1047: skb->dev = dev; ! 1048: if (! rx_in_place) { ! 1049: skb_reserve(skb, 2); /* 16 byte align the data fields */ ! 1050: memcpy(skb_put(skb, pkt_len), ! 1051: bus_to_virt(lp->rx_ring[entry].addr), pkt_len); ! 1052: } ! 1053: #if LINUX_VERSION_CODE > 0x10300 ! 1054: skb->protocol = eth_type_trans(skb, dev); ! 1055: #else ! 1056: skb->len = pkt_len; ! 1057: #endif ! 1058: netif_rx(skb); ! 1059: lp->stats.rx_packets++; ! 1060: } ! 1061: ! 1062: /* Mark this entry as being the end-of-list, and the prior entry ! 1063: as now valid. */ ! 1064: lp->rx_ring[entry].cmd = CMD_STOP; ! 1065: yp->rx_ring[entry].status = 0; ! 1066: { ! 1067: int prev_entry = entry - 1; ! 1068: if (prev_entry < 0) ! 1069: lp->rx_ring[RX_RING_SIZE - 1].cmd = ! 1070: CMD_RX_BUF | INTR_ALWAYS | BRANCH_ALWAYS; ! 1071: else ! 1072: lp->rx_ring[prev_entry].cmd = CMD_RX_BUF | INTR_ALWAYS; ! 1073: } ! 1074: entry = (++lp->cur_rx) % RX_RING_SIZE; ! 1075: } ! 1076: /* todo: restart Rx engine if stopped. For now we just make the Rx ring ! 1077: large enough to avoid this. */ ! 1078: ! 1079: return 0; ! 1080: } ! 1081: ! 1082: static int ! 1083: yellowfin_close(struct device *dev) ! 1084: { ! 1085: int ioaddr = dev->base_addr; ! 1086: struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; ! 1087: int i; ! 1088: ! 1089: dev->start = 0; ! 1090: dev->tbusy = 1; ! 1091: ! 1092: if (yellowfin_debug > 1) { ! 1093: printk("%s: Shutting down ethercard, status was Tx %4.4x Rx %4.4x Int %2.2x.\n", ! 1094: dev->name, inw(ioaddr + TxStatus), ! 1095: inw(ioaddr + RxStatus), inl(ioaddr + IntrStatus)); ! 1096: printk("%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", ! 1097: dev->name, yp->cur_tx, yp->dirty_tx, yp->cur_rx, yp->dirty_rx); ! 1098: } ! 1099: ! 1100: /* Disable interrupts by clearing the interrupt mask. */ ! 1101: outw(0x0000, ioaddr + IntrEnb); ! 1102: ! 1103: /* Stop the chip's Tx and Rx processes. */ ! 1104: outl(0x80000000, ioaddr + RxCtrl); ! 1105: outl(0x80000000, ioaddr + TxCtrl); ! 1106: ! 1107: del_timer(&yp->timer); ! 1108: ! 1109: #ifdef __i386__ ! 1110: if (yellowfin_debug > 2) { ! 1111: printk("\n Tx ring at %8.8x:\n", (int)virt_to_bus(yp->tx_ring)); ! 1112: for (i = 0; i < TX_RING_SIZE*2; i++) ! 1113: printk(" %c #%d desc. %4.4x %4.4x %8.8x %8.8x %4.4x %4.4x.\n", ! 1114: inl(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ', ! 1115: i, yp->tx_ring[i].cmd, ! 1116: yp->tx_ring[i].request_cnt, yp->tx_ring[i].addr, ! 1117: yp->tx_ring[i].branch_addr, ! 1118: yp->tx_ring[i].result_cnt, yp->tx_ring[i].status); ! 1119: printk(" Tx status %p:\n", yp->tx_status); ! 1120: for (i = 0; i < TX_RING_SIZE; i++) ! 1121: printk(" #%d status %4.4x %4.4x %4.4x %4.4x.\n", ! 1122: i, yp->tx_status[i].tx_cnt, yp->tx_status[i].tx_errs, ! 1123: yp->tx_status[i].total_tx_cnt, yp->tx_status[i].paused); ! 1124: ! 1125: printk("\n Rx ring %8.8x:\n", (int)virt_to_bus(yp->rx_ring)); ! 1126: for (i = 0; i < RX_RING_SIZE; i++) { ! 1127: printk(" %c #%d desc. %4.4x %4.4x %8.8x %4.4x %4.4x\n", ! 1128: inl(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ', ! 1129: i, yp->rx_ring[i].cmd, ! 1130: yp->rx_ring[i].request_cnt, yp->rx_ring[i].addr, ! 1131: yp->rx_ring[i].result_cnt, yp->rx_ring[i].status); ! 1132: if (yellowfin_debug > 5) { ! 1133: if (*(u8*)yp->rx_ring[i].addr != 0x69) { ! 1134: int j; ! 1135: for (j = 0; j < 0x50; j++) ! 1136: printk(" %4.4x", ((u16*)yp->rx_ring[i].addr)[j]); ! 1137: printk("\n"); ! 1138: } ! 1139: } ! 1140: } ! 1141: } ! 1142: #endif /* __i386__ debugging only */ ! 1143: ! 1144: #ifdef SA_SHIRQ ! 1145: free_irq(dev->irq, dev); ! 1146: #else ! 1147: free_irq(dev->irq); ! 1148: irq2dev_map[dev->irq] = 0; ! 1149: #endif ! 1150: ! 1151: /* Free all the skbuffs in the Rx queue. */ ! 1152: for (i = 0; i < RX_RING_SIZE; i++) { ! 1153: yp->rx_ring[i].cmd = CMD_STOP; ! 1154: yp->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */ ! 1155: if (yp->rx_skbuff[i]) { ! 1156: #if LINUX_VERSION_CODE < 0x20100 ! 1157: yp->rx_skbuff[i]->free = 1; ! 1158: #endif ! 1159: dev_kfree_skb(yp->rx_skbuff[i], FREE_WRITE); ! 1160: } ! 1161: yp->rx_skbuff[i] = 0; ! 1162: } ! 1163: for (i = 0; i < TX_RING_SIZE; i++) { ! 1164: if (yp->tx_skbuff[i]) ! 1165: dev_kfree_skb(yp->tx_skbuff[i], FREE_WRITE); ! 1166: yp->tx_skbuff[i] = 0; ! 1167: } ! 1168: ! 1169: #ifdef YF_PROTOTYPE /* Support for prototype hardware errata. */ ! 1170: if (yellowfin_debug > 0) { ! 1171: printk("%s: Received %d frames that we should not have.\n", ! 1172: dev->name, bogus_rx); ! 1173: } ! 1174: #endif ! 1175: MOD_DEC_USE_COUNT; ! 1176: ! 1177: return 0; ! 1178: } ! 1179: ! 1180: static struct enet_statistics * ! 1181: yellowfin_get_stats(struct device *dev) ! 1182: { ! 1183: struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; ! 1184: return &yp->stats; ! 1185: } ! 1186: ! 1187: /* Set or clear the multicast filter for this adaptor. */ ! 1188: ! 1189: /* The little-endian AUTODIN32 ethernet CRC calculation. ! 1190: N.B. Do not use for bulk data, use a table-based routine instead. ! 1191: This is common code and should be moved to net/core/crc.c */ ! 1192: static unsigned const ethernet_polynomial_le = 0xedb88320U; ! 1193: static inline unsigned ether_crc_le(int length, unsigned char *data) ! 1194: { ! 1195: unsigned int crc = 0xffffffff; /* Initial value. */ ! 1196: while(--length >= 0) { ! 1197: unsigned char current_octet = *data++; ! 1198: int bit; ! 1199: for (bit = 8; --bit >= 0; current_octet >>= 1) { ! 1200: if ((crc ^ current_octet) & 1) { ! 1201: crc >>= 1; ! 1202: crc ^= ethernet_polynomial_le; ! 1203: } else ! 1204: crc >>= 1; ! 1205: } ! 1206: } ! 1207: return crc; ! 1208: } ! 1209: ! 1210: ! 1211: #ifdef NEW_MULTICAST ! 1212: static void set_rx_mode(struct device *dev) ! 1213: #else ! 1214: static void set_rx_mode(struct device *dev, int num_addrs, void *addrs); ! 1215: #endif ! 1216: { ! 1217: int ioaddr = dev->base_addr; ! 1218: u16 cfg_value = inw(ioaddr + Cnfg); ! 1219: ! 1220: /* Stop the Rx process to change any value. */ ! 1221: outw(cfg_value & ~0x1000, ioaddr + Cnfg); ! 1222: if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ ! 1223: /* Unconditionally log net taps. */ ! 1224: printk("%s: Promiscuous mode enabled.\n", dev->name); ! 1225: outw(0x000F, ioaddr + AddrMode); ! 1226: } else if ((dev->mc_count > 64) || (dev->flags & IFF_ALLMULTI)) { ! 1227: /* Too many to filter well, or accept all multicasts. */ ! 1228: outw(0x000B, ioaddr + AddrMode); ! 1229: } else if (dev->mc_count > 0) { /* Must use the multicast hash table. */ ! 1230: struct dev_mc_list *mclist; ! 1231: u16 hash_table[4]; ! 1232: int i; ! 1233: memset(hash_table, 0, sizeof(hash_table)); ! 1234: for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; ! 1235: i++, mclist = mclist->next) { ! 1236: /* Due to a bug in the early chip versions, multiple filter ! 1237: slots must be set for each address. */ ! 1238: set_bit((ether_crc_le(3, mclist->dmi_addr) >> 3) & 0x3f, ! 1239: hash_table); ! 1240: set_bit((ether_crc_le(4, mclist->dmi_addr) >> 3) & 0x3f, ! 1241: hash_table); ! 1242: set_bit((ether_crc_le(5, mclist->dmi_addr) >> 3) & 0x3f, ! 1243: hash_table); ! 1244: set_bit((ether_crc_le(6, mclist->dmi_addr) >> 3) & 0x3f, ! 1245: hash_table); ! 1246: } ! 1247: /* Copy the hash table to the chip. */ ! 1248: for (i = 0; i < 4; i++) ! 1249: outw(hash_table[i], ioaddr + HashTbl + i*2); ! 1250: outw(0x0003, ioaddr + AddrMode); ! 1251: } else { /* Normal, unicast/broadcast-only mode. */ ! 1252: outw(0x0001, ioaddr + AddrMode); ! 1253: } ! 1254: /* Restart the Rx process. */ ! 1255: outw(cfg_value | 0x1000, ioaddr + Cnfg); ! 1256: } ! 1257: ! 1258: #ifdef MODULE ! 1259: ! 1260: /* An additional parameter that may be passed in... */ ! 1261: static int debug = -1; ! 1262: ! 1263: int ! 1264: init_module(void) ! 1265: { ! 1266: int cards_found; ! 1267: ! 1268: if (debug >= 0) ! 1269: yellowfin_debug = debug; ! 1270: ! 1271: root_yellowfin_dev = NULL; ! 1272: cards_found = yellowfin_probe(0); ! 1273: ! 1274: return cards_found ? 0 : -ENODEV; ! 1275: } ! 1276: ! 1277: void ! 1278: cleanup_module(void) ! 1279: { ! 1280: struct device *next_dev; ! 1281: ! 1282: /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ ! 1283: while (root_yellowfin_dev) { ! 1284: next_dev = ((struct yellowfin_private *)root_yellowfin_dev->priv)->next_module; ! 1285: unregister_netdev(root_yellowfin_dev); ! 1286: release_region(root_yellowfin_dev->base_addr, YELLOWFIN_TOTAL_SIZE); ! 1287: kfree(root_yellowfin_dev); ! 1288: root_yellowfin_dev = next_dev; ! 1289: } ! 1290: } ! 1291: ! 1292: #endif /* MODULE */ ! 1293: ! 1294: /* ! 1295: * Local variables: ! 1296: * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c yellowfin.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" ! 1297: * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c yellowfin.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" ! 1298: * c-indent-level: 4 ! 1299: * c-basic-offset: 4 ! 1300: * tab-width: 4 ! 1301: * End: ! 1302: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.