|
|
1.1 ! root 1: /* hamachi.c: A Packet Engines GNIC-II Gigabit Ethernet driver for Linux. */ ! 2: /* ! 3: Written 1998-2002 by Donald Becker. ! 4: ! 5: This software may be used and distributed according to the terms of ! 6: the GNU General Public License (GPL), incorporated herein by reference. ! 7: Drivers based on or derived from this code fall under the GPL and must ! 8: retain the authorship, copyright and license notice. This file is not ! 9: a complete program and may only be used when the entire operating ! 10: system is licensed under the GPL. ! 11: ! 12: The author may be reached as [email protected], or C/O ! 13: Scyld Computing Corporation ! 14: 410 Severn Ave., Suite 210 ! 15: Annapolis MD 21403 ! 16: ! 17: This driver is for the Packet Engines GNIC-II PCI Gigabit Ethernet ! 18: adapter. ! 19: ! 20: Support and updates available at ! 21: http://www.scyld.com/network/hamachi.html ! 22: */ ! 23: ! 24: /* These identify the driver base version and may not be removed. */ ! 25: static const char version1[] = ! 26: "hamachi.c:v1.04 11/17/2002 Written by Donald Becker <[email protected]>\n"; ! 27: static const char version2[] = ! 28: " http://www.scyld.com/network/hamachi.html\n"; ! 29: ! 30: /* Automatically extracted configuration info: ! 31: probe-func: hamachi_probe ! 32: config-in: tristate 'Packet Engines "Hamachi" PCI Gigabit Ethernet support' CONFIG_HAMACHI ! 33: c-help-name: Packet Engines "Hamachi" PCI Gigabit Ethernet support ! 34: c-help-symbol: CONFIG_HAMACHI ! 35: c-help: This driver is for the Packet Engines "Hamachi" GNIC-2 Gigabit Ethernet ! 36: c-help: adapter. ! 37: c-help: Usage information and updates are available from ! 38: c-help: http://www.scyld.com/network/hamachi.html ! 39: */ ! 40: ! 41: /* The user-configurable values. ! 42: These may be modified when a driver module is loaded.*/ ! 43: ! 44: /* Message enable level: 0..31 = no..all messages. See NETIF_MSG docs. */ ! 45: static int debug = 2; ! 46: ! 47: /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ ! 48: static int max_interrupt_work = 40; ! 49: ! 50: /* Maximum number of multicast addresses to filter (vs. rx-all-multicast). ! 51: The Hamachi has a 64 element perfect filter. */ ! 52: static int multicast_filter_limit = 32; ! 53: ! 54: /* Set the copy breakpoint for the copy-only-tiny-frames scheme. ! 55: Setting to > 1518 effectively disables this feature. */ ! 56: static int rx_copybreak = 0; ! 57: ! 58: /* A override for the hardware detection of bus width. ! 59: Set to 1 to force 32 bit PCI bus detection. Set to 4 to force 64 bit. ! 60: Add 2 to disable parity detection. ! 61: */ ! 62: static int force32 = 0; ! 63: ! 64: /* Used to pass the media type, etc. ! 65: These exist for driver interoperability. ! 66: Only 1 Gigabit is supported by the chip. ! 67: */ ! 68: #define MAX_UNITS 8 /* More are supported, limit only on options */ ! 69: static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; ! 70: static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; ! 71: ! 72: /* Operational parameters that are set at compile time. */ ! 73: ! 74: /* Keep the ring sizes a power of two for compile efficiency. ! 75: The compiler will convert <unsigned>'%'<2^N> into a bit mask. ! 76: Making the Tx ring too large decreases the effectiveness of channel ! 77: bonding and packet priority. ! 78: There are no ill effects from too-large receive rings. */ ! 79: #define TX_RING_SIZE 64 ! 80: #define TX_QUEUE_LEN 60 /* Limit ring entries actually used. */ ! 81: #define RX_RING_SIZE 128 ! 82: ! 83: /* Operational parameters that usually are not changed. */ ! 84: /* Time in jiffies before concluding the transmitter is hung. */ ! 85: #define TX_TIMEOUT (6*HZ) ! 86: ! 87: /* Allocation size of Rx buffers with normal sized Ethernet frames. ! 88: Do not change this value without good reason. This is not a limit, ! 89: but a way to keep a consistent allocation size among drivers. ! 90: */ ! 91: #define PKT_BUF_SZ 1536 ! 92: ! 93: #ifndef __KERNEL__ ! 94: #define __KERNEL__ ! 95: #endif ! 96: #if !defined(__OPTIMIZE__) ! 97: #warning You must compile this file with the correct options! ! 98: #warning See the last lines of the source file. ! 99: #error You must compile this driver with "-O". ! 100: #endif ! 101: ! 102: #include <linux/config.h> ! 103: #if defined(CONFIG_SMP) && ! defined(__SMP__) ! 104: #define __SMP__ ! 105: #endif ! 106: #if defined(MODULE) && defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS) ! 107: #define MODVERSIONS ! 108: #endif ! 109: ! 110: #include <linux/version.h> ! 111: #if defined(MODVERSIONS) ! 112: #include <linux/modversions.h> ! 113: #endif ! 114: #include <linux/module.h> ! 115: ! 116: #include <linux/kernel.h> ! 117: #include <linux/string.h> ! 118: #include <linux/timer.h> ! 119: #include <linux/errno.h> ! 120: #include <linux/ioport.h> ! 121: #if LINUX_VERSION_CODE >= 0x20400 ! 122: #include <linux/slab.h> ! 123: #else ! 124: #include <linux/malloc.h> ! 125: #endif ! 126: #include <linux/interrupt.h> ! 127: #include <linux/pci.h> ! 128: #include <linux/netdevice.h> ! 129: #include <linux/etherdevice.h> ! 130: #include <linux/skbuff.h> ! 131: #include <asm/processor.h> /* Processor type for cache alignment. */ ! 132: #include <asm/bitops.h> ! 133: #include <asm/io.h> ! 134: #include <asm/unaligned.h> ! 135: ! 136: #ifdef INLINE_PCISCAN ! 137: #include "k_compat.h" ! 138: #else ! 139: #include "pci-scan.h" ! 140: #include "kern_compat.h" ! 141: #endif ! 142: ! 143: /* Condensed operations for readability. */ ! 144: #if ADDRLEN == 64 ! 145: #define virt_to_desc(addr) cpu_to_le64(virt_to_bus(addr)) ! 146: #else ! 147: #define virt_to_desc(addr) cpu_to_le32(virt_to_bus(addr)) ! 148: #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) ! 149: #endif ! 150: ! 151: #if (LINUX_VERSION_CODE >= 0x20100) && defined(MODULE) ! 152: char kernel_version[] = UTS_RELEASE; ! 153: #endif ! 154: ! 155: MODULE_AUTHOR("Donald Becker <[email protected]>"); ! 156: MODULE_DESCRIPTION("Packet Engines 'Hamachi' GNIC-II Gigabit Ethernet driver"); ! 157: MODULE_LICENSE("GPL"); ! 158: MODULE_PARM(debug, "i"); ! 159: MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); ! 160: MODULE_PARM(rx_copybreak, "i"); ! 161: MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); ! 162: MODULE_PARM(multicast_filter_limit, "i"); ! 163: MODULE_PARM(max_interrupt_work, "i"); ! 164: MODULE_PARM(force32, "i"); ! 165: MODULE_PARM_DESC(debug, "Driver message level (0-31)"); ! 166: MODULE_PARM_DESC(options, "Force transceiver type or fixed speed+duplex"); ! 167: MODULE_PARM_DESC(max_interrupt_work, ! 168: "Driver maximum events handled per interrupt"); ! 169: MODULE_PARM_DESC(full_duplex, ! 170: "Non-zero to force full duplex, non-negotiated link " ! 171: "(unused, deprecated)."); ! 172: MODULE_PARM_DESC(rx_copybreak, ! 173: "Breakpoint in bytes for copy-only-tiny-frames"); ! 174: MODULE_PARM_DESC(multicast_filter_limit, ! 175: "Multicast addresses before switching to Rx-all-multicast"); ! 176: MODULE_PARM_DESC(force32, "Set to 1 to force 32 bit PCI bus use."); ! 177: ! 178: /* ! 179: Theory of Operation ! 180: ! 181: I. Board Compatibility ! 182: ! 183: This device driver is designed for the Packet Engines "Hamachi" ! 184: Gigabit Ethernet chip. The only PCA currently supported is the GNIC-II 64-bit ! 185: 66Mhz PCI card. ! 186: ! 187: II. Board-specific settings ! 188: ! 189: No jumpers exist on the board. The chip supports software correction of ! 190: various motherboard wiring errors, however this driver does not support ! 191: that feature. ! 192: ! 193: III. Driver operation ! 194: ! 195: IIIa. Ring buffers ! 196: ! 197: The Hamachi uses a typical descriptor based bus-master architecture. ! 198: The descriptor list is similar to that used by the Digital Tulip. ! 199: This driver uses two statically allocated fixed-size descriptor lists ! 200: formed into rings by a branch from the final descriptor to the beginning of ! 201: the list. The ring sizes are set at compile time by RX/TX_RING_SIZE. ! 202: ! 203: This driver uses a zero-copy receive and transmit scheme similar my other ! 204: network drivers. ! 205: The driver allocates full frame size skbuffs for the Rx ring buffers at ! 206: open() time and passes the skb->data field to the Hamachi as receive data ! 207: buffers. When an incoming frame is less than RX_COPYBREAK bytes long, ! 208: a fresh skbuff is allocated and the frame is copied to the new skbuff. ! 209: When the incoming frame is larger, the skbuff is passed directly up the ! 210: protocol stack and replaced by a newly allocated skbuff. ! 211: ! 212: The RX_COPYBREAK value is chosen to trade-off the memory wasted by ! 213: using a full-sized skbuff for small frames vs. the copying costs of larger ! 214: frames. Gigabit cards are typically used on generously configured machines ! 215: and the underfilled buffers have negligible impact compared to the benefit of ! 216: a single allocation size, so the default value of zero results in never ! 217: copying packets. ! 218: ! 219: IIIb/c. Transmit/Receive Structure ! 220: ! 221: The Rx and Tx descriptor structure are straight-forward, with no historical ! 222: baggage that must be explained. Unlike the awkward DBDMA structure, there ! 223: are no unused fields or option bits that had only one allowable setting. ! 224: ! 225: Two details should be noted about the descriptors: The chip supports both 32 ! 226: bit and 64 bit address structures, and the length field is overwritten on ! 227: the receive descriptors. The descriptor length is set in the control word ! 228: for each channel. The development driver uses 32 bit addresses only, however ! 229: 64 bit addresses may be enabled for 64 bit architectures e.g. the Alpha. ! 230: ! 231: IIId. Synchronization ! 232: ! 233: This driver is very similar to my other network drivers. ! 234: The driver runs as two independent, single-threaded flows of control. One ! 235: is the send-packet routine, which enforces single-threaded use by the ! 236: dev->tbusy flag. The other thread is the interrupt handler, which is single ! 237: threaded by the hardware and other software. ! 238: ! 239: The send packet thread has partial control over the Tx ring and 'dev->tbusy' ! 240: flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next ! 241: queue slot is empty, it clears the tbusy flag when finished otherwise it sets ! 242: the 'hmp->tx_full' flag. ! 243: ! 244: The interrupt handler has exclusive control over the Rx ring and records stats ! 245: from the Tx ring. After reaping the stats, it marks the Tx queue entry as ! 246: empty by incrementing the dirty_tx mark. Iff the 'hmp->tx_full' flag is set, it ! 247: clears both the tx_full and tbusy flags. ! 248: ! 249: IV. Notes ! 250: ! 251: Thanks to Kim Stearns of Packet Engines for providing a pair of GNIC-II boards. ! 252: ! 253: IVb. References ! 254: ! 255: Hamachi Engineering Design Specification, 5/15/97 ! 256: (Note: This version was marked "Confidential".) ! 257: ! 258: IVc. Errata ! 259: ! 260: None noted. ! 261: */ ! 262: ! 263: ! 264: /* The table for PCI detection and activation. */ ! 265: ! 266: static void *hamachi_probe1(struct pci_dev *pdev, void *init_dev, ! 267: long ioaddr, int irq, int chip_idx, int find_cnt); ! 268: enum chip_capability_flags { CanHaveMII=1, }; ! 269: ! 270: static struct pci_id_info pci_id_tbl[] = { ! 271: {"Packet Engines GNIC-II \"Hamachi\"", { 0x09111318, 0xffffffff,}, ! 272: PCI_USES_MEM | PCI_USES_MASTER | PCI_ADDR0 | PCI_ADDR_64BITS, 0x400, 0, }, ! 273: { 0,}, ! 274: }; ! 275: ! 276: struct drv_id_info hamachi_drv_id = { ! 277: "hamachi", 0, PCI_CLASS_NETWORK_ETHERNET<<8, pci_id_tbl, ! 278: hamachi_probe1, 0, ! 279: }; ! 280: ! 281: /* Offsets to the Hamachi registers. Various sizes. */ ! 282: enum hamachi_offsets { ! 283: TxDMACtrl=0x00, TxCmd=0x04, TxStatus=0x06, TxPtr=0x08, TxCurPtr=0x10, ! 284: RxDMACtrl=0x20, RxCmd=0x24, RxStatus=0x26, RxPtr=0x28, RxCurPtr=0x30, ! 285: PCIClkMeas=0x060, MiscStatus=0x066, ChipRev=0x68, ChipReset=0x06B, ! 286: LEDCtrl=0x06C, VirtualJumpers=0x06D, ! 287: TxChecksum=0x074, RxChecksum=0x076, ! 288: TxIntrCtrl=0x078, RxIntrCtrl=0x07C, ! 289: InterruptEnable=0x080, InterruptClear=0x084, IntrStatus=0x088, ! 290: EventStatus=0x08C, ! 291: MACCnfg=0x0A0, FrameGap0=0x0A2, FrameGap1=0x0A4, ! 292: /* See enum MII_offsets below. */ ! 293: MACCnfg2=0x0B0, RxDepth=0x0B8, FlowCtrl=0x0BC, MaxFrameSize=0x0CE, ! 294: AddrMode=0x0D0, StationAddr=0x0D2, ! 295: /* Gigabit AutoNegotiation. */ ! 296: ANCtrl=0x0E0, ANStatus=0x0E2, ANXchngCtrl=0x0E4, ANAdvertise=0x0E8, ! 297: ANLinkPartnerAbility=0x0EA, ! 298: EECmdStatus=0x0F0, EEData=0x0F1, EEAddr=0x0F2, ! 299: FIFOcfg=0x0F8, ! 300: }; ! 301: ! 302: /* Offsets to the MII-mode registers. */ ! 303: enum MII_offsets { ! 304: MII_Cmd=0xA6, MII_Addr=0xA8, MII_Wr_Data=0xAA, MII_Rd_Data=0xAC, ! 305: MII_Status=0xAE, ! 306: }; ! 307: ! 308: /* Bits in the interrupt status/mask registers. */ ! 309: enum intr_status_bits { ! 310: IntrRxDone=0x01, IntrRxPCIFault=0x02, IntrRxPCIErr=0x04, ! 311: IntrTxDone=0x100, IntrTxPCIFault=0x200, IntrTxPCIErr=0x400, ! 312: LinkChange=0x10000, NegotiationChange=0x20000, StatsMax=0x40000, }; ! 313: ! 314: /* The Hamachi Rx and Tx buffer descriptors. */ ! 315: struct hamachi_desc { ! 316: u32 status_n_length; ! 317: #if ADDRLEN == 64 ! 318: u32 pad; ! 319: u64 addr; ! 320: #else ! 321: u32 addr; ! 322: #endif ! 323: }; ! 324: ! 325: /* Bits in hamachi_desc.status */ ! 326: enum desc_status_bits { ! 327: DescOwn=0x80000000, DescEndPacket=0x40000000, DescEndRing=0x20000000, ! 328: DescIntr=0x10000000, ! 329: }; ! 330: ! 331: #define PRIV_ALIGN 15 /* Required alignment mask */ ! 332: struct hamachi_private { ! 333: /* Descriptor rings first for alignment. Tx requires a second descriptor ! 334: for status. */ ! 335: struct hamachi_desc rx_ring[RX_RING_SIZE]; ! 336: struct hamachi_desc tx_ring[TX_RING_SIZE]; ! 337: /* The addresses of receive-in-place skbuffs. */ ! 338: struct sk_buff* rx_skbuff[RX_RING_SIZE]; ! 339: /* The saved address of a sent-in-place packet/buffer, for skfree(). */ ! 340: struct sk_buff* tx_skbuff[TX_RING_SIZE]; ! 341: struct net_device *next_module; ! 342: void *priv_addr; /* Unaligned address for kfree */ ! 343: struct net_device_stats stats; ! 344: struct timer_list timer; /* Media monitoring timer. */ ! 345: int chip_id, drv_flags; ! 346: struct pci_dev *pci_dev; ! 347: ! 348: /* Frequently used and paired value: keep adjacent for cache effect. */ ! 349: int msg_level; ! 350: int max_interrupt_work; ! 351: long in_interrupt; ! 352: ! 353: struct hamachi_desc *rx_head_desc; ! 354: unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */ ! 355: unsigned int rx_buf_sz; /* Based on MTU+slack. */ ! 356: int rx_copybreak; ! 357: int multicast_filter_limit; ! 358: int rx_mode; ! 359: ! 360: unsigned int cur_tx, dirty_tx; ! 361: unsigned int tx_full:1; /* The Tx queue is full. */ ! 362: unsigned int full_duplex:1; /* Full-duplex operation requested. */ ! 363: unsigned int duplex_lock:1; ! 364: unsigned int medialock:1; /* Do not sense media. */ ! 365: unsigned int default_port; /* Last dev->if_port value. */ ! 366: /* MII transceiver section. */ ! 367: int mii_cnt; /* MII device addresses. */ ! 368: u16 advertising; /* NWay media advertisement */ ! 369: unsigned char phys[2]; /* MII device addresses. */ ! 370: }; ! 371: ! 372: static int read_eeprom(struct net_device *dev, int location); ! 373: static int mdio_read(long ioaddr, int phy_id, int location); ! 374: static void mdio_write(long ioaddr, int phy_id, int location, int value); ! 375: static int hamachi_open(struct net_device *dev); ! 376: static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); ! 377: #ifdef HAVE_CHANGE_MTU ! 378: static int change_mtu(struct net_device *dev, int new_mtu); ! 379: #endif ! 380: static void hamachi_timer(unsigned long data); ! 381: static void hamachi_tx_timeout(struct net_device *dev); ! 382: static void hamachi_init_ring(struct net_device *dev); ! 383: static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev); ! 384: static void hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *regs); ! 385: static int hamachi_rx(struct net_device *dev); ! 386: static void hamachi_error(struct net_device *dev, int intr_status); ! 387: static int hamachi_close(struct net_device *dev); ! 388: static struct net_device_stats *hamachi_get_stats(struct net_device *dev); ! 389: static void set_rx_mode(struct net_device *dev); ! 390: ! 391: ! 392: ! 393: /* A list of our installed devices, for removing the driver module. */ ! 394: static struct net_device *root_hamachi_dev = NULL; ! 395: ! 396: #ifndef MODULE ! 397: int hamachi_probe(struct net_device *dev) ! 398: { ! 399: if (pci_drv_register(&hamachi_drv_id, dev) < 0) ! 400: return -ENODEV; ! 401: printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); ! 402: return 0; ! 403: } ! 404: #endif ! 405: ! 406: static void *hamachi_probe1(struct pci_dev *pdev, void *init_dev, ! 407: long ioaddr, int irq, int chip_idx, int card_idx) ! 408: { ! 409: struct net_device *dev; ! 410: struct hamachi_private *np; ! 411: void *priv_mem; ! 412: int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0; ! 413: ! 414: dev = init_etherdev(init_dev, 0); ! 415: if (!dev) ! 416: return NULL; ! 417: ! 418: printk(KERN_INFO "%s: %s type %x at 0x%lx, ", ! 419: dev->name, pci_id_tbl[chip_idx].name, (int)readl(ioaddr + ChipRev), ! 420: ioaddr); ! 421: ! 422: for (i = 0; i < 6; i++) ! 423: dev->dev_addr[i] = read_eeprom(dev, 4 + i); ! 424: /* Alternate: readb(ioaddr + StationAddr + i); */ ! 425: for (i = 0; i < 5; i++) ! 426: printk("%2.2x:", dev->dev_addr[i]); ! 427: printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); ! 428: ! 429: i = readb(ioaddr + PCIClkMeas); ! 430: printk(KERN_INFO "%s: %d-bit %d Mhz PCI bus (%d), Virtual Jumpers " ! 431: "%2.2x, LPA %4.4x.\n", ! 432: dev->name, readw(ioaddr + MiscStatus) & 1 ? 64 : 32, ! 433: i ? 2000/(i&0x7f) : 0, i&0x7f, (int)readb(ioaddr + VirtualJumpers), ! 434: (int)readw(ioaddr + ANLinkPartnerAbility)); ! 435: ! 436: /* Hmmm, do we really need to reset the chip???. */ ! 437: writeb(1, ioaddr + ChipReset); ! 438: ! 439: /* If the bus size is misidentified, do the following. */ ! 440: if (force32) ! 441: writeb(force32, ioaddr + VirtualJumpers); ! 442: ! 443: /* Make certain elements e.g. descriptor lists are aligned. */ ! 444: priv_mem = kmalloc(sizeof(*np) + PRIV_ALIGN, GFP_KERNEL); ! 445: /* Check for the very unlikely case of no memory. */ ! 446: if (priv_mem == NULL) ! 447: return NULL; ! 448: ! 449: dev->base_addr = ioaddr; ! 450: dev->irq = irq; ! 451: ! 452: dev->priv = np = (void *)(((long)priv_mem + PRIV_ALIGN) & ~PRIV_ALIGN); ! 453: memset(np, 0, sizeof(*np)); ! 454: np->priv_addr = priv_mem; ! 455: ! 456: np->next_module = root_hamachi_dev; ! 457: root_hamachi_dev = dev; ! 458: ! 459: np->pci_dev = pdev; ! 460: np->chip_id = chip_idx; ! 461: np->drv_flags = pci_id_tbl[chip_idx].drv_flags; ! 462: np->msg_level = (1 << debug) - 1; ! 463: np->rx_copybreak = rx_copybreak; ! 464: np->max_interrupt_work = max_interrupt_work; ! 465: np->multicast_filter_limit = ! 466: multicast_filter_limit < 64 ? multicast_filter_limit : 64; ! 467: ! 468: if (dev->mem_start) ! 469: option = dev->mem_start; ! 470: ! 471: /* The lower four bits are the media type. */ ! 472: if (option > 0) { ! 473: if (option & 0x2220) ! 474: np->full_duplex = 1; ! 475: np->default_port = option & 15; ! 476: if (np->default_port & 0x3330) ! 477: np->medialock = 1; ! 478: } ! 479: if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0) ! 480: np->full_duplex = 1; ! 481: ! 482: if (np->full_duplex) { ! 483: if (np->msg_level & NETIF_MSG_PROBE) ! 484: printk(KERN_INFO "%s: Set to forced full duplex, autonegotiation" ! 485: " disabled.\n", dev->name); ! 486: np->duplex_lock = 1; ! 487: } ! 488: ! 489: /* The Hamachi-specific entries in the device structure. */ ! 490: dev->open = &hamachi_open; ! 491: dev->hard_start_xmit = &hamachi_start_xmit; ! 492: dev->stop = &hamachi_close; ! 493: dev->get_stats = &hamachi_get_stats; ! 494: dev->set_multicast_list = &set_rx_mode; ! 495: dev->do_ioctl = &mii_ioctl; ! 496: #ifdef HAVE_CHANGE_MTU ! 497: dev->change_mtu = change_mtu; ! 498: #endif ! 499: ! 500: if (np->drv_flags & CanHaveMII) { ! 501: int phy, phy_idx = 0; ! 502: for (phy = 0; phy < 32 && phy_idx < 4; phy++) { ! 503: int mii_status = mdio_read(ioaddr, phy, 1); ! 504: if (mii_status != 0xffff && mii_status != 0x0000) { ! 505: np->phys[phy_idx++] = phy; ! 506: np->advertising = mdio_read(ioaddr, phy, 4); ! 507: printk(KERN_INFO "%s: MII PHY found at address %d, status " ! 508: "0x%4.4x advertising %4.4x.\n", ! 509: dev->name, phy, mii_status, np->advertising); ! 510: } ! 511: } ! 512: np->mii_cnt = phy_idx; ! 513: } ! 514: #ifdef notyet ! 515: /* Disable PCI Parity Error (0x02) or PCI 64 Bit (0x01) for miswired ! 516: motherboards. */ ! 517: if (readb(ioaddr + VirtualJumpers) != 0x30) ! 518: writeb(0x33, ioaddr + VirtualJumpers) ! 519: #endif ! 520: /* Configure gigabit autonegotiation. */ ! 521: writew(0x0400, ioaddr + ANXchngCtrl); /* Enable legacy links. */ ! 522: writew(0x08e0, ioaddr + ANAdvertise); /* Set our advertise word. */ ! 523: writew(0x1000, ioaddr + ANCtrl); /* Enable negotiation */ ! 524: ! 525: return dev; ! 526: } ! 527: ! 528: static int read_eeprom(struct net_device *dev, int location) ! 529: { ! 530: struct hamachi_private *np = (void *)dev->priv; ! 531: long ioaddr = dev->base_addr; ! 532: int bogus_cnt = 1000; ! 533: ! 534: writew(location, ioaddr + EEAddr); ! 535: writeb(0x02, ioaddr + EECmdStatus); ! 536: while ((readb(ioaddr + EECmdStatus) & 0x40) && --bogus_cnt > 0) ! 537: ; ! 538: if (np->msg_level & NETIF_MSG_MISC) ! 539: printk(KERN_DEBUG " EEPROM status is %2.2x after %d ticks.\n", ! 540: (int)readb(ioaddr + EECmdStatus), 1000- bogus_cnt); ! 541: return readb(ioaddr + EEData); ! 542: } ! 543: ! 544: /* MII Managemen Data I/O accesses. ! 545: These routines assume the MDIO controller is idle, and do not exit until ! 546: the command is finished. */ ! 547: ! 548: static int mdio_read(long ioaddr, int phy_id, int location) ! 549: { ! 550: int i; ! 551: ! 552: writew((phy_id<<8) + location, ioaddr + MII_Addr); ! 553: writew(1, ioaddr + MII_Cmd); ! 554: for (i = 10000; i >= 0; i--) ! 555: if ((readw(ioaddr + MII_Status) & 1) == 0) ! 556: break; ! 557: return readw(ioaddr + MII_Rd_Data); ! 558: } ! 559: ! 560: static void mdio_write(long ioaddr, int phy_id, int location, int value) ! 561: { ! 562: int i; ! 563: ! 564: writew((phy_id<<8) + location, ioaddr + MII_Addr); ! 565: writew(value, ioaddr + MII_Wr_Data); ! 566: ! 567: /* Wait for the command to finish. */ ! 568: for (i = 10000; i >= 0; i--) ! 569: if ((readw(ioaddr + MII_Status) & 1) == 0) ! 570: break; ! 571: return; ! 572: } ! 573: ! 574: ! 575: static int hamachi_open(struct net_device *dev) ! 576: { ! 577: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 578: long ioaddr = dev->base_addr; ! 579: int i; ! 580: ! 581: /* Do we need to reset the chip??? */ ! 582: ! 583: MOD_INC_USE_COUNT; ! 584: ! 585: if (request_irq(dev->irq, &hamachi_interrupt, SA_SHIRQ, dev->name, dev)) { ! 586: MOD_DEC_USE_COUNT; ! 587: return -EAGAIN; ! 588: } ! 589: ! 590: if (hmp->msg_level & NETIF_MSG_IFUP) ! 591: printk(KERN_DEBUG "%s: hamachi_open() irq %d.\n", ! 592: dev->name, dev->irq); ! 593: ! 594: hamachi_init_ring(dev); ! 595: ! 596: #if ADDRLEN == 64 ! 597: writel(virt_to_bus(hmp->rx_ring), ioaddr + RxPtr); ! 598: writel(virt_to_bus(hmp->rx_ring) >> 32, ioaddr + RxPtr + 4); ! 599: writel(virt_to_bus(hmp->tx_ring), ioaddr + TxPtr); ! 600: writel(virt_to_bus(hmp->tx_ring) >> 32, ioaddr + TxPtr + 4); ! 601: #else ! 602: writel(virt_to_bus(hmp->rx_ring), ioaddr + RxPtr); ! 603: writel(virt_to_bus(hmp->tx_ring), ioaddr + TxPtr); ! 604: #endif ! 605: ! 606: for (i = 0; i < 6; i++) ! 607: writeb(dev->dev_addr[i], ioaddr + StationAddr + i); ! 608: ! 609: /* Initialize other registers: with so many this eventually this will ! 610: converted to an offset/value list. */ ! 611: /* Configure the FIFO for 512K external, 16K used for Tx. */ ! 612: writew(0x0028, ioaddr + FIFOcfg); ! 613: ! 614: if (dev->if_port == 0) ! 615: dev->if_port = hmp->default_port; ! 616: hmp->in_interrupt = 0; ! 617: ! 618: /* Setting the Rx mode will start the Rx process. */ ! 619: /* We are always in full-duplex mode with gigabit! */ ! 620: hmp->full_duplex = 1; ! 621: writew(0x0001, ioaddr + RxChecksum); /* Enable Rx IP partial checksum. */ ! 622: writew(0x8000, ioaddr + MACCnfg); /* Soft reset the MAC */ ! 623: writew(0x215F, ioaddr + MACCnfg); ! 624: writew(0x000C, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */ ! 625: writew(0x1018, ioaddr + FrameGap1); ! 626: writew(0x2780, ioaddr + MACCnfg2); /* Upper 16 bits control LEDs. */ ! 627: /* Enable automatic generation of flow control frames, period 0xffff. */ ! 628: writel(0x0030FFFF, ioaddr + FlowCtrl); ! 629: writew(dev->mtu+19, ioaddr + MaxFrameSize); /* hmp->rx_buf_sz ??? */ ! 630: ! 631: /* Enable legacy links. */ ! 632: writew(0x0400, ioaddr + ANXchngCtrl); /* Enable legacy links. */ ! 633: /* Initial Link LED to blinking red. */ ! 634: writeb(0x03, ioaddr + LEDCtrl); ! 635: ! 636: /* Configure interrupt mitigation. This has a great effect on ! 637: performance, so systems tuning should start here!. */ ! 638: writel(0x00080000, ioaddr + TxIntrCtrl); ! 639: writel(0x00000020, ioaddr + RxIntrCtrl); ! 640: ! 641: hmp->rx_mode = 0; /* Force Rx mode write. */ ! 642: set_rx_mode(dev); ! 643: netif_start_tx_queue(dev); ! 644: ! 645: /* Enable interrupts by setting the interrupt mask. */ ! 646: writel(0x80878787, ioaddr + InterruptEnable); ! 647: writew(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */ ! 648: ! 649: /* Configure and start the DMA channels. */ ! 650: /* Burst sizes are in the low three bits: size = 4<<(val&7) */ ! 651: #if ADDRLEN == 64 ! 652: writew(0x0055, ioaddr + RxDMACtrl); /* 128 dword bursts */ ! 653: writew(0x0055, ioaddr + TxDMACtrl); ! 654: #else ! 655: writew(0x0015, ioaddr + RxDMACtrl); ! 656: writew(0x0015, ioaddr + TxDMACtrl); ! 657: #endif ! 658: writew(1, dev->base_addr + RxCmd); ! 659: ! 660: if (hmp->msg_level & NETIF_MSG_IFUP) ! 661: printk(KERN_DEBUG "%s: Done hamachi_open(), status: Rx %x Tx %x.\n", ! 662: dev->name, (int)readw(ioaddr + RxStatus), ! 663: (int)readw(ioaddr + TxStatus)); ! 664: ! 665: /* Set the timer to check for link beat. */ ! 666: init_timer(&hmp->timer); ! 667: hmp->timer.expires = jiffies + 3*HZ; ! 668: hmp->timer.data = (unsigned long)dev; ! 669: hmp->timer.function = &hamachi_timer; /* timer handler */ ! 670: add_timer(&hmp->timer); ! 671: ! 672: return 0; ! 673: } ! 674: ! 675: static void hamachi_timer(unsigned long data) ! 676: { ! 677: struct net_device *dev = (struct net_device *)data; ! 678: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 679: long ioaddr = dev->base_addr; ! 680: int next_tick = 10*HZ; ! 681: ! 682: if (hmp->msg_level & NETIF_MSG_TIMER) { ! 683: printk(KERN_INFO "%s: Hamachi Autonegotiation status %4.4x, LPA " ! 684: "%4.4x.\n", dev->name, (int)readw(ioaddr + ANStatus), ! 685: (int)readw(ioaddr + ANLinkPartnerAbility)); ! 686: printk(KERN_INFO "%s: Autonegotiation regs %4.4x %4.4x %4.4x " ! 687: "%4.4x %4.4x %4.4x.\n", dev->name, ! 688: (int)readw(ioaddr + 0x0e0), ! 689: (int)readw(ioaddr + 0x0e2), ! 690: (int)readw(ioaddr + 0x0e4), ! 691: (int)readw(ioaddr + 0x0e6), ! 692: (int)readw(ioaddr + 0x0e8), ! 693: (int)readw(ioaddr + 0x0eA)); ! 694: } ! 695: /* This has a small false-trigger window. */ ! 696: if (netif_queue_paused(dev) && ! 697: (jiffies - dev->trans_start) > TX_TIMEOUT ! 698: && hmp->cur_tx - hmp->dirty_tx > 1) { ! 699: hamachi_tx_timeout(dev); ! 700: } ! 701: /* We could do something here... nah. */ ! 702: hmp->timer.expires = jiffies + next_tick; ! 703: add_timer(&hmp->timer); ! 704: } ! 705: ! 706: static void hamachi_tx_timeout(struct net_device *dev) ! 707: { ! 708: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 709: long ioaddr = dev->base_addr; ! 710: ! 711: printk(KERN_WARNING "%s: Hamachi transmit timed out, status %8.8x," ! 712: " resetting...\n", dev->name, (int)readw(ioaddr + TxStatus)); ! 713: ! 714: if (hmp->msg_level & NETIF_MSG_TX_ERR) { ! 715: int i; ! 716: printk(KERN_DEBUG " Rx ring %p: ", hmp->rx_ring); ! 717: for (i = 0; i < RX_RING_SIZE; i++) ! 718: printk(" %8.8x", (unsigned int)hmp->rx_ring[i].status_n_length); ! 719: printk("\n"KERN_DEBUG" Tx ring %p: ", hmp->tx_ring); ! 720: for (i = 0; i < TX_RING_SIZE; i++) ! 721: printk(" %4.4x", hmp->tx_ring[i].status_n_length); ! 722: printk("\n"); ! 723: } ! 724: ! 725: /* Perhaps we should reinitialize the hardware here. */ ! 726: dev->if_port = 0; ! 727: /* Stop and restart the chip's Tx processes . */ ! 728: ! 729: /* Trigger an immediate transmit demand. */ ! 730: writew(2, dev->base_addr + TxCmd); ! 731: writew(1, dev->base_addr + TxCmd); ! 732: writew(1, dev->base_addr + RxCmd); ! 733: ! 734: dev->trans_start = jiffies; ! 735: hmp->stats.tx_errors++; ! 736: return; ! 737: } ! 738: ! 739: ! 740: /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ ! 741: static void hamachi_init_ring(struct net_device *dev) ! 742: { ! 743: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 744: int i; ! 745: ! 746: hmp->tx_full = 0; ! 747: hmp->cur_rx = hmp->cur_tx = 0; ! 748: hmp->dirty_rx = hmp->dirty_tx = 0; ! 749: ! 750: /* Size of each temporary Rx buffer. Add 8 if you do Rx checksumming! */ ! 751: hmp->rx_buf_sz = dev->mtu + 18 + 8; ! 752: /* Match other driver's allocation size when possible. */ ! 753: if (hmp->rx_buf_sz < PKT_BUF_SZ) ! 754: hmp->rx_buf_sz = PKT_BUF_SZ; ! 755: hmp->rx_head_desc = &hmp->rx_ring[0]; ! 756: ! 757: /* Initialize all Rx descriptors. */ ! 758: for (i = 0; i < RX_RING_SIZE; i++) { ! 759: hmp->rx_ring[i].status_n_length = 0; ! 760: hmp->rx_skbuff[i] = 0; ! 761: } ! 762: /* Fill in the Rx buffers. Handle allocation failure gracefully. */ ! 763: for (i = 0; i < RX_RING_SIZE; i++) { ! 764: struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz); ! 765: hmp->rx_skbuff[i] = skb; ! 766: if (skb == NULL) ! 767: break; ! 768: skb->dev = dev; /* Mark as being used by this device. */ ! 769: skb_reserve(skb, 2); /* 16 byte align the IP header. */ ! 770: hmp->rx_ring[i].addr = virt_to_desc(skb->tail); ! 771: hmp->rx_ring[i].status_n_length = ! 772: cpu_to_le32(DescOwn | DescEndPacket | DescIntr | hmp->rx_buf_sz); ! 773: } ! 774: hmp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); ! 775: /* Mark the last entry as wrapping the ring. */ ! 776: hmp->rx_ring[i-1].status_n_length |= cpu_to_le32(DescEndRing); ! 777: ! 778: for (i = 0; i < TX_RING_SIZE; i++) { ! 779: hmp->tx_skbuff[i] = 0; ! 780: hmp->tx_ring[i].status_n_length = 0; ! 781: } ! 782: return; ! 783: } ! 784: ! 785: static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev) ! 786: { ! 787: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 788: unsigned entry; ! 789: ! 790: /* Block a timer-based transmit from overlapping. This could better be ! 791: done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ ! 792: if (netif_pause_tx_queue(dev) != 0) { ! 793: /* This watchdog code is redundant with the media monitor timer. */ ! 794: if (jiffies - dev->trans_start > TX_TIMEOUT) ! 795: hamachi_tx_timeout(dev); ! 796: return 1; ! 797: } ! 798: ! 799: /* Note: Ordering is important here, set the field with the ! 800: "ownership" bit last, and only then increment cur_tx. */ ! 801: ! 802: /* Calculate the next Tx descriptor entry. */ ! 803: entry = hmp->cur_tx % TX_RING_SIZE; ! 804: ! 805: hmp->tx_skbuff[entry] = skb; ! 806: ! 807: hmp->tx_ring[entry].addr = virt_to_desc(skb->data); ! 808: if (entry >= TX_RING_SIZE-1) /* Wrap ring */ ! 809: hmp->tx_ring[entry].status_n_length = ! 810: cpu_to_le32(DescOwn|DescEndPacket|DescEndRing|DescIntr | skb->len); ! 811: else ! 812: hmp->tx_ring[entry].status_n_length = ! 813: cpu_to_le32(DescOwn|DescEndPacket | skb->len); ! 814: hmp->cur_tx++; ! 815: ! 816: /* Architecture-specific: explicitly flush cache lines here. */ ! 817: ! 818: /* Wake the potentially-idle transmit channel. */ ! 819: writew(1, dev->base_addr + TxCmd); ! 820: ! 821: if (hmp->cur_tx - hmp->dirty_tx >= TX_QUEUE_LEN - 1) { ! 822: hmp->tx_full = 1; ! 823: if (hmp->cur_tx - hmp->dirty_tx < TX_QUEUE_LEN - 1) { ! 824: netif_unpause_tx_queue(dev); ! 825: hmp->tx_full = 0; ! 826: } else ! 827: netif_stop_tx_queue(dev); ! 828: } else ! 829: netif_unpause_tx_queue(dev); /* Typical path */ ! 830: dev->trans_start = jiffies; ! 831: ! 832: if (hmp->msg_level & NETIF_MSG_TX_QUEUED) { ! 833: printk(KERN_DEBUG "%s: Hamachi transmit frame #%d length %d queued " ! 834: "in slot %d.\n", dev->name, hmp->cur_tx, (int)skb->len, entry); ! 835: } ! 836: return 0; ! 837: } ! 838: ! 839: /* The interrupt handler does all of the Rx thread work and cleans up ! 840: after the Tx thread. */ ! 841: static void hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs) ! 842: { ! 843: struct net_device *dev = (struct net_device *)dev_instance; ! 844: struct hamachi_private *hmp; ! 845: long ioaddr; ! 846: int boguscnt = max_interrupt_work; ! 847: ! 848: #ifndef final_version /* Can never occur. */ ! 849: if (dev == NULL) { ! 850: printk (KERN_ERR "hamachi_interrupt(): irq %d for unknown device.\n", irq); ! 851: return; ! 852: } ! 853: #endif ! 854: ! 855: ioaddr = dev->base_addr; ! 856: hmp = (struct hamachi_private *)dev->priv; ! 857: if (test_and_set_bit(0, (void*)&hmp->in_interrupt)) { ! 858: printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name); ! 859: hmp->in_interrupt = 0; /* Avoid future hang on bug */ ! 860: return; ! 861: } ! 862: ! 863: do { ! 864: u32 intr_status = readl(ioaddr + InterruptClear); ! 865: ! 866: if (hmp->msg_level & NETIF_MSG_INTR) ! 867: printk(KERN_DEBUG "%s: Hamachi interrupt, status %4.4x.\n", ! 868: dev->name, intr_status); ! 869: ! 870: if (intr_status == 0) ! 871: break; ! 872: ! 873: if (intr_status & IntrRxDone) ! 874: hamachi_rx(dev); ! 875: ! 876: for (; hmp->cur_tx - hmp->dirty_tx > 0; hmp->dirty_tx++) { ! 877: int entry = hmp->dirty_tx % TX_RING_SIZE; ! 878: if (!(hmp->tx_ring[entry].status_n_length & cpu_to_le32(DescOwn))) ! 879: break; ! 880: if (hmp->msg_level & NETIF_MSG_TX_DONE) ! 881: printk(KERN_DEBUG "%s: Transmit done, Tx status %8.8x.\n", ! 882: dev->name, hmp->tx_ring[entry].status_n_length); ! 883: /* Free the original skb. */ ! 884: dev_free_skb_irq(hmp->tx_skbuff[entry]); ! 885: hmp->tx_skbuff[entry] = 0; ! 886: hmp->stats.tx_packets++; ! 887: } ! 888: if (hmp->tx_full ! 889: && hmp->cur_tx - hmp->dirty_tx < TX_QUEUE_LEN - 4) { ! 890: /* The ring is no longer full, clear tbusy. */ ! 891: hmp->tx_full = 0; ! 892: netif_resume_tx_queue(dev); ! 893: } ! 894: ! 895: /* Abnormal error summary/uncommon events handlers. */ ! 896: if (intr_status & ! 897: (IntrTxPCIFault | IntrTxPCIErr | IntrRxPCIFault | IntrRxPCIErr | ! 898: LinkChange | NegotiationChange | StatsMax)) ! 899: hamachi_error(dev, intr_status); ! 900: ! 901: if (--boguscnt < 0) { ! 902: printk(KERN_WARNING "%s: Too much work at interrupt, " ! 903: "status=0x%4.4x.\n", ! 904: dev->name, intr_status); ! 905: break; ! 906: } ! 907: } while (1); ! 908: ! 909: if (hmp->msg_level & NETIF_MSG_INTR) ! 910: printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", ! 911: dev->name, (int)readl(ioaddr + IntrStatus)); ! 912: clear_bit(0, (void*)&hmp->in_interrupt); ! 913: return; ! 914: } ! 915: ! 916: /* This routine is logically part of the interrupt handler, but separated ! 917: for clarity and better register allocation. */ ! 918: static int hamachi_rx(struct net_device *dev) ! 919: { ! 920: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 921: int entry = hmp->cur_rx % RX_RING_SIZE; ! 922: int boguscnt = hmp->dirty_rx + RX_RING_SIZE - hmp->cur_rx; ! 923: ! 924: if (hmp->msg_level & NETIF_MSG_RX_STATUS) { ! 925: printk(KERN_DEBUG " In hamachi_rx(), entry %d status %4.4x.\n", ! 926: entry, hmp->rx_ring[entry].status_n_length); ! 927: } ! 928: ! 929: /* If EOP is set on the next entry, it's a new packet. Send it up. */ ! 930: while ( ! (hmp->rx_head_desc->status_n_length & cpu_to_le32(DescOwn))) { ! 931: struct hamachi_desc *desc = hmp->rx_head_desc; ! 932: u32 desc_status = le32_to_cpu(desc->status_n_length); ! 933: u16 data_size = desc_status; /* Implicit truncate */ ! 934: u8 *buf_addr = hmp->rx_skbuff[entry]->tail; ! 935: s32 frame_status = ! 936: le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12]))); ! 937: ! 938: if (hmp->msg_level & NETIF_MSG_RX_STATUS) ! 939: printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n", ! 940: frame_status); ! 941: if (--boguscnt < 0) ! 942: break; ! 943: if ( ! (desc_status & DescEndPacket)) { ! 944: printk(KERN_WARNING "%s: Oversized Ethernet frame spanned " ! 945: "multiple buffers, entry %#x length %d status %4.4x!\n", ! 946: dev->name, hmp->cur_rx, data_size, desc_status); ! 947: printk(KERN_WARNING "%s: Oversized Ethernet frame %p vs %p.\n", ! 948: dev->name, desc, &hmp->rx_ring[hmp->cur_rx % RX_RING_SIZE]); ! 949: printk(KERN_WARNING "%s: Oversized Ethernet frame -- next status" ! 950: " %x last status %x.\n", dev->name, ! 951: hmp->rx_ring[(hmp->cur_rx+1) % RX_RING_SIZE].status_n_length, ! 952: hmp->rx_ring[(hmp->cur_rx-1) % RX_RING_SIZE].status_n_length); ! 953: hmp->stats.rx_length_errors++; ! 954: } /* else Omit for prototype errata??? */ ! 955: if (frame_status & 0x00380000) { ! 956: /* There was a error. */ ! 957: if (hmp->msg_level & NETIF_MSG_RX_ERR) ! 958: printk(KERN_DEBUG " hamachi_rx() Rx error was %8.8x.\n", ! 959: frame_status); ! 960: hmp->stats.rx_errors++; ! 961: if (frame_status & 0x00600000) hmp->stats.rx_length_errors++; ! 962: if (frame_status & 0x00080000) hmp->stats.rx_frame_errors++; ! 963: if (frame_status & 0x00100000) hmp->stats.rx_crc_errors++; ! 964: if (frame_status < 0) hmp->stats.rx_dropped++; ! 965: } else { ! 966: struct sk_buff *skb; ! 967: u16 pkt_len = (frame_status & 0x07ff) - 4; /* Omit CRC */ ! 968: ! 969: #if ! defined(final_version) && 0 ! 970: if (hmp->msg_level & NETIF_MSG_RX_STATUS) ! 971: printk(KERN_DEBUG " hamachi_rx() normal Rx pkt length %d" ! 972: " of %d, bogus_cnt %d.\n", ! 973: pkt_len, data_size, boguscnt); ! 974: if (hmp->msg_level & NETIF_MSG_PKTDATA) ! 975: printk(KERN_DEBUG"%s: rx status %8.8x %8.8x %8.8x %8.8x %8.8x.\n", ! 976: dev->name, ! 977: *(s32*)&(buf_addr[data_size - 20]), ! 978: *(s32*)&(buf_addr[data_size - 16]), ! 979: *(s32*)&(buf_addr[data_size - 12]), ! 980: *(s32*)&(buf_addr[data_size - 8]), ! 981: *(s32*)&(buf_addr[data_size - 4])); ! 982: #endif ! 983: /* Check if the packet is long enough to accept without copying ! 984: to a minimally-sized skbuff. */ ! 985: if (pkt_len < rx_copybreak ! 986: && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { ! 987: skb->dev = dev; ! 988: skb_reserve(skb, 2); /* 16 byte align the IP header */ ! 989: eth_copy_and_sum(skb, hmp->rx_skbuff[entry]->tail, pkt_len, 0); ! 990: skb_put(skb, pkt_len); ! 991: } else { ! 992: char *temp = skb_put(skb = hmp->rx_skbuff[entry], pkt_len); ! 993: hmp->rx_skbuff[entry] = NULL; ! 994: #if ! defined(final_version) ! 995: if (bus_to_virt(desc->addr) != temp) ! 996: printk(KERN_ERR "%s: Internal fault: The skbuff addresses " ! 997: "do not match in hamachi_rx: %p vs. %p / %p.\n", ! 998: dev->name, bus_to_virt(desc->addr), ! 999: skb->head, temp); ! 1000: #endif ! 1001: } ! 1002: skb->protocol = eth_type_trans(skb, dev); ! 1003: /* Note: checksum -> skb->ip_summed = CHECKSUM_UNNECESSARY; */ ! 1004: netif_rx(skb); ! 1005: dev->last_rx = jiffies; ! 1006: hmp->stats.rx_packets++; ! 1007: } ! 1008: entry = (++hmp->cur_rx) % RX_RING_SIZE; ! 1009: hmp->rx_head_desc = &hmp->rx_ring[entry]; ! 1010: } ! 1011: ! 1012: /* Refill the Rx ring buffers. */ ! 1013: for (; hmp->cur_rx - hmp->dirty_rx > 0; hmp->dirty_rx++) { ! 1014: struct sk_buff *skb; ! 1015: entry = hmp->dirty_rx % RX_RING_SIZE; ! 1016: if (hmp->rx_skbuff[entry] == NULL) { ! 1017: skb = dev_alloc_skb(hmp->rx_buf_sz); ! 1018: hmp->rx_skbuff[entry] = skb; ! 1019: if (skb == NULL) ! 1020: break; /* Better luck next round. */ ! 1021: skb->dev = dev; /* Mark as being used by this device. */ ! 1022: skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ ! 1023: hmp->rx_ring[entry].addr = virt_to_desc(skb->tail); ! 1024: } ! 1025: if (entry >= RX_RING_SIZE-1) /* Wrap ring */ ! 1026: hmp->rx_ring[entry].status_n_length = ! 1027: cpu_to_le32(DescOwn|DescEndPacket|DescEndRing|DescIntr | hmp->rx_buf_sz); ! 1028: else ! 1029: hmp->rx_ring[entry].status_n_length = ! 1030: cpu_to_le32(DescOwn|DescEndPacket|DescIntr | hmp->rx_buf_sz); ! 1031: } ! 1032: ! 1033: /* Restart Rx engine if stopped. */ ! 1034: writew(1, dev->base_addr + RxCmd); ! 1035: return 0; ! 1036: } ! 1037: ! 1038: /* This is more properly named "uncommon interrupt events", as it covers more ! 1039: than just errors. */ ! 1040: static void hamachi_error(struct net_device *dev, int intr_status) ! 1041: { ! 1042: long ioaddr = dev->base_addr; ! 1043: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 1044: ! 1045: if (intr_status & (LinkChange|NegotiationChange)) { ! 1046: if (hmp->msg_level & NETIF_MSG_LINK) ! 1047: printk(KERN_INFO "%s: Link changed: AutoNegotiation Ctrl" ! 1048: " %4.4x, Status %4.4x %4.4x Intr status %4.4x.\n", ! 1049: dev->name, (int)readw(ioaddr + 0x0E0), ! 1050: (int)readw(ioaddr + 0x0E2), ! 1051: (int)readw(ioaddr + ANLinkPartnerAbility), ! 1052: (int)readl(ioaddr + IntrStatus)); ! 1053: if (readw(ioaddr + ANStatus) & 0x20) { ! 1054: writeb(0x01, ioaddr + LEDCtrl); ! 1055: netif_link_up(dev); ! 1056: } else { ! 1057: writeb(0x03, ioaddr + LEDCtrl); ! 1058: netif_link_down(dev); ! 1059: } ! 1060: } ! 1061: if (intr_status & StatsMax) { ! 1062: hamachi_get_stats(dev); ! 1063: /* Read the overflow bits to clear. */ ! 1064: readl(ioaddr + 0x36C); ! 1065: readl(ioaddr + 0x3F0); ! 1066: } ! 1067: if ((intr_status & ~(LinkChange|StatsMax|NegotiationChange)) ! 1068: && (hmp->msg_level & NETIF_MSG_DRV)) ! 1069: printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n", ! 1070: dev->name, intr_status); ! 1071: /* Hmmmmm, it's not clear how to recover from PCI faults. */ ! 1072: if (intr_status & (IntrTxPCIErr | IntrTxPCIFault)) ! 1073: hmp->stats.tx_fifo_errors++; ! 1074: if (intr_status & (IntrRxPCIErr | IntrRxPCIFault)) ! 1075: hmp->stats.rx_fifo_errors++; ! 1076: } ! 1077: ! 1078: static int hamachi_close(struct net_device *dev) ! 1079: { ! 1080: long ioaddr = dev->base_addr; ! 1081: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 1082: int i; ! 1083: ! 1084: netif_stop_tx_queue(dev); ! 1085: ! 1086: if (hmp->msg_level & NETIF_MSG_IFDOWN) { ! 1087: printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x " ! 1088: "Rx %4.4x Int %2.2x.\n", ! 1089: dev->name, (int)readw(ioaddr + TxStatus), ! 1090: (int)readw(ioaddr + RxStatus), (int)readl(ioaddr + IntrStatus)); ! 1091: printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", ! 1092: dev->name, hmp->cur_tx, hmp->dirty_tx, hmp->cur_rx, ! 1093: hmp->dirty_rx); ! 1094: } ! 1095: ! 1096: /* Disable interrupts by clearing the interrupt mask. */ ! 1097: writel(0x0000, ioaddr + InterruptEnable); ! 1098: ! 1099: /* Stop the chip's Tx and Rx processes. */ ! 1100: writel(2, ioaddr + RxCmd); ! 1101: writew(2, ioaddr + TxCmd); ! 1102: ! 1103: del_timer(&hmp->timer); ! 1104: ! 1105: #ifdef __i386__ ! 1106: if (hmp->msg_level & NETIF_MSG_IFDOWN) { ! 1107: printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", ! 1108: (int)virt_to_bus(hmp->tx_ring)); ! 1109: for (i = 0; i < TX_RING_SIZE; i++) ! 1110: printk(" %c #%d desc. %8.8x %8.8x.\n", ! 1111: readl(ioaddr + TxCurPtr) == (long)&hmp->tx_ring[i] ? '>' : ' ', ! 1112: i, hmp->tx_ring[i].status_n_length, hmp->tx_ring[i].addr); ! 1113: printk("\n"KERN_DEBUG " Rx ring %8.8x:\n", ! 1114: (int)virt_to_bus(hmp->rx_ring)); ! 1115: for (i = 0; i < RX_RING_SIZE; i++) { ! 1116: printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x\n", ! 1117: readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ', ! 1118: i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr); ! 1119: if (*(u8*)hmp->rx_ring[i].addr != 0x69) { ! 1120: int j; ! 1121: for (j = 0; j < 0x50; j++) ! 1122: printk(" %4.4x", ((u16*)hmp->rx_ring[i].addr)[j]); ! 1123: printk("\n"); ! 1124: } ! 1125: } ! 1126: } ! 1127: #endif /* __i386__ debugging only */ ! 1128: ! 1129: free_irq(dev->irq, dev); ! 1130: ! 1131: /* Free all the skbuffs in the Rx queue. */ ! 1132: for (i = 0; i < RX_RING_SIZE; i++) { ! 1133: hmp->rx_ring[i].status_n_length = 0; ! 1134: hmp->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */ ! 1135: if (hmp->rx_skbuff[i]) { ! 1136: #if LINUX_VERSION_CODE < 0x20100 ! 1137: hmp->rx_skbuff[i]->free = 1; ! 1138: #endif ! 1139: dev_free_skb(hmp->rx_skbuff[i]); ! 1140: } ! 1141: hmp->rx_skbuff[i] = 0; ! 1142: } ! 1143: for (i = 0; i < TX_RING_SIZE; i++) { ! 1144: if (hmp->tx_skbuff[i]) ! 1145: dev_free_skb(hmp->tx_skbuff[i]); ! 1146: hmp->tx_skbuff[i] = 0; ! 1147: } ! 1148: ! 1149: writeb(0x00, ioaddr + LEDCtrl); ! 1150: ! 1151: MOD_DEC_USE_COUNT; ! 1152: ! 1153: return 0; ! 1154: } ! 1155: ! 1156: static struct net_device_stats *hamachi_get_stats(struct net_device *dev) ! 1157: { ! 1158: long ioaddr = dev->base_addr; ! 1159: struct hamachi_private *hmp = (struct hamachi_private *)dev->priv; ! 1160: ! 1161: /* We should lock this segment of code for SMP eventually, although ! 1162: the vulnerability window is very small and statistics are ! 1163: non-critical. */ ! 1164: #if LINUX_VERSION_CODE >= 0x20119 ! 1165: hmp->stats.rx_bytes += readl(ioaddr + 0x330); /* Total Uni+Brd+Multi */ ! 1166: hmp->stats.tx_bytes += readl(ioaddr + 0x3B0); /* Total Uni+Brd+Multi */ ! 1167: #endif ! 1168: hmp->stats.multicast += readl(ioaddr + 0x320); /* Multicast Rx */ ! 1169: ! 1170: hmp->stats.rx_length_errors += readl(ioaddr + 0x368); /* Over+Undersized */ ! 1171: hmp->stats.rx_over_errors += readl(ioaddr + 0x35C); /* Jabber */ ! 1172: hmp->stats.rx_crc_errors += readl(ioaddr + 0x360); ! 1173: hmp->stats.rx_frame_errors += readl(ioaddr + 0x364); /* Symbol Errs */ ! 1174: hmp->stats.rx_missed_errors += readl(ioaddr + 0x36C); /* Dropped */ ! 1175: ! 1176: return &hmp->stats; ! 1177: } ! 1178: ! 1179: static void set_rx_mode(struct net_device *dev) ! 1180: { ! 1181: struct hamachi_private *np = (void *)dev->priv; ! 1182: long ioaddr = dev->base_addr; ! 1183: int new_rx_mode; ! 1184: ! 1185: if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ ! 1186: /* Unconditionally log net taps. */ ! 1187: printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); ! 1188: new_rx_mode = 0x000F; ! 1189: } else if (dev->mc_count > np->multicast_filter_limit || ! 1190: (dev->flags & IFF_ALLMULTI)) { ! 1191: /* Too many to match, or accept all multicasts. */ ! 1192: new_rx_mode = 0x000B; ! 1193: } else if (dev->mc_count > 0) { /* Must use the CAM filter. */ ! 1194: struct dev_mc_list *mclist; ! 1195: int i; ! 1196: for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; ! 1197: i++, mclist = mclist->next) { ! 1198: writel(*(u32*)(mclist->dmi_addr), ioaddr + 0x100 + i*8); ! 1199: writel(0x20000 | (*(u16*)&mclist->dmi_addr[4]), ! 1200: ioaddr + 0x104 + i*8); ! 1201: } ! 1202: /* Clear remaining entries. */ ! 1203: for (; i < 64; i++) ! 1204: writel(0, ioaddr + 0x104 + i*8); ! 1205: new_rx_mode = 0x0003; ! 1206: } else { /* Normal, unicast/broadcast-only mode. */ ! 1207: new_rx_mode = 0x0001; ! 1208: } ! 1209: if (np->rx_mode != new_rx_mode) { ! 1210: np->rx_mode = new_rx_mode; ! 1211: writew(new_rx_mode, ioaddr + AddrMode); ! 1212: } ! 1213: } ! 1214: ! 1215: static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ! 1216: { ! 1217: struct hamachi_private *np = (void *)dev->priv; ! 1218: long ioaddr = dev->base_addr; ! 1219: u16 *data = (u16 *)&rq->ifr_data; ! 1220: u32 *data32 = (void *)&rq->ifr_data; ! 1221: ! 1222: switch(cmd) { ! 1223: case 0x8947: case 0x89F0: ! 1224: /* SIOCGMIIPHY: Get the address of the PHY in use. */ ! 1225: data[0] = np->phys[0] & 0x1f; ! 1226: /* Fall Through */ ! 1227: case 0x8948: case 0x89F1: ! 1228: /* SIOCGMIIREG: Read the specified MII register. */ ! 1229: data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f); ! 1230: return 0; ! 1231: case 0x8949: case 0x89F2: ! 1232: /* SIOCSMIIREG: Write the specified MII register */ ! 1233: if (!capable(CAP_NET_ADMIN)) ! 1234: return -EPERM; ! 1235: /* We are always full duplex. Skip recording the advertised value. */ ! 1236: mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]); ! 1237: return 0; ! 1238: case SIOCGPARAMS: ! 1239: data32[0] = np->msg_level; ! 1240: data32[1] = np->multicast_filter_limit; ! 1241: data32[2] = np->max_interrupt_work; ! 1242: data32[3] = np->rx_copybreak; ! 1243: return 0; ! 1244: case SIOCSPARAMS: { ! 1245: /* Set rx,tx intr params, from Eric Kasten. */ ! 1246: if (!capable(CAP_NET_ADMIN)) ! 1247: return -EPERM; ! 1248: np->msg_level = data32[0]; ! 1249: np->max_interrupt_work = data32[2]; ! 1250: writel(data32[1], dev->base_addr + TxIntrCtrl); ! 1251: writel(data32[3], dev->base_addr + RxIntrCtrl); ! 1252: printk(KERN_INFO "%s: Set interrupt mitigate paramters tx %08x, " ! 1253: "rx %08x.\n", dev->name, ! 1254: (int) readl(dev->base_addr + TxIntrCtrl), ! 1255: (int) readl(dev->base_addr + RxIntrCtrl)); ! 1256: return 0; ! 1257: } ! 1258: default: ! 1259: return -EOPNOTSUPP; ! 1260: } ! 1261: } ! 1262: ! 1263: #ifdef HAVE_CHANGE_MTU ! 1264: static int change_mtu(struct net_device *dev, int new_mtu) ! 1265: { ! 1266: if ((new_mtu < 68) || (new_mtu > 1536)) ! 1267: return -EINVAL; ! 1268: if (netif_running(dev)) ! 1269: return -EBUSY; ! 1270: printk(KERN_NOTICE "%s: Changing MTU to %d.\n", dev->name, new_mtu); ! 1271: dev->mtu = new_mtu; ! 1272: return 0; ! 1273: } ! 1274: #endif ! 1275: ! 1276: ! 1277: #ifdef MODULE ! 1278: int init_module(void) ! 1279: { ! 1280: if (debug >= NETIF_MSG_DRV) /* Emit version even if no cards detected. */ ! 1281: printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); ! 1282: return pci_drv_register(&hamachi_drv_id, NULL); ! 1283: } ! 1284: ! 1285: void cleanup_module(void) ! 1286: { ! 1287: struct net_device *next_dev; ! 1288: ! 1289: pci_drv_unregister(&hamachi_drv_id); ! 1290: ! 1291: /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ ! 1292: while (root_hamachi_dev) { ! 1293: struct hamachi_private *hmp = (void *)(root_hamachi_dev->priv); ! 1294: unregister_netdev(root_hamachi_dev); ! 1295: iounmap((char *)root_hamachi_dev->base_addr); ! 1296: next_dev = hmp->next_module; ! 1297: if (hmp->priv_addr) ! 1298: kfree(hmp->priv_addr); ! 1299: kfree(root_hamachi_dev); ! 1300: root_hamachi_dev = next_dev; ! 1301: } ! 1302: } ! 1303: ! 1304: #endif /* MODULE */ ! 1305: ! 1306: /* ! 1307: * Local variables: ! 1308: * compile-command: "make KERNVER=`uname -r` hamachi.o" ! 1309: * compile-cmd: "gcc -DMODULE -Wall -Wstrict-prototypes -O6 -c hamachi.c" ! 1310: * simple-compile-command: "gcc -DMODULE -O6 -c hamachi.c" ! 1311: * c-indent-level: 4 ! 1312: * c-basic-offset: 4 ! 1313: * tab-width: 4 ! 1314: * End: ! 1315: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.