diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-07-31 00:06:29 -0700 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-08-27 00:58:13 -0700 |
commit | 33f810b2036f13f1b123062a9e5c1794d400ce81 (patch) | |
tree | 370b55026f4bd856e96842f86af631ca2bab3da2 /drivers/net/defxx.c | |
parent | 3cd0999d134235d64b175edd2eb1d46ebc97b377 (diff) |
fddi: Move the FDDI drivers
Move the FDDI drivers into drivers/net/fddi/ and make the
necessary Kconfig and Makefile changes.
CC: "Maciej W. Rozycki" <macro@linux-mips.org>
CC: Christoph Goos <cgoos@syskonnect.de>
CC: <linux@syskonnect.de>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/defxx.c')
-rw-r--r-- | drivers/net/defxx.c | 3739 |
1 files changed, 0 insertions, 3739 deletions
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c deleted file mode 100644 index 4ad80f77109..00000000000 --- a/drivers/net/defxx.c +++ /dev/null @@ -1,3739 +0,0 @@ -/* - * File Name: - * defxx.c - * - * Copyright Information: - * Copyright Digital Equipment Corporation 1996. - * - * This software may be used and distributed according to the terms of - * the GNU General Public License, incorporated herein by reference. - * - * Abstract: - * A Linux device driver supporting the Digital Equipment Corporation - * FDDI TURBOchannel, EISA and PCI controller families. Supported - * adapters include: - * - * DEC FDDIcontroller/TURBOchannel (DEFTA) - * DEC FDDIcontroller/EISA (DEFEA) - * DEC FDDIcontroller/PCI (DEFPA) - * - * The original author: - * LVS Lawrence V. Stefani <lstefani@yahoo.com> - * - * Maintainers: - * macro Maciej W. Rozycki <macro@linux-mips.org> - * - * Credits: - * I'd like to thank Patricia Cross for helping me get started with - * Linux, David Davies for a lot of help upgrading and configuring - * my development system and for answering many OS and driver - * development questions, and Alan Cox for recommendations and - * integration help on getting FDDI support into Linux. LVS - * - * Driver Architecture: - * The driver architecture is largely based on previous driver work - * for other operating systems. The upper edge interface and - * functions were largely taken from existing Linux device drivers - * such as David Davies' DE4X5.C driver and Donald Becker's TULIP.C - * driver. - * - * Adapter Probe - - * The driver scans for supported EISA adapters by reading the - * SLOT ID register for each EISA slot and making a match - * against the expected value. - * - * Bus-Specific Initialization - - * This driver currently supports both EISA and PCI controller - * families. While the custom DMA chip and FDDI logic is similar - * or identical, the bus logic is very different. After - * initialization, the only bus-specific differences is in how the - * driver enables and disables interrupts. Other than that, the - * run-time critical code behaves the same on both families. - * It's important to note that both adapter families are configured - * to I/O map, rather than memory map, the adapter registers. - * - * Driver Open/Close - - * In the driver open routine, the driver ISR (interrupt service - * routine) is registered and the adapter is brought to an - * operational state. In the driver close routine, the opposite - * occurs; the driver ISR is deregistered and the adapter is - * brought to a safe, but closed state. Users may use consecutive - * commands to bring the adapter up and down as in the following - * example: - * ifconfig fddi0 up - * ifconfig fddi0 down - * ifconfig fddi0 up - * - * Driver Shutdown - - * Apparently, there is no shutdown or halt routine support under - * Linux. This routine would be called during "reboot" or - * "shutdown" to allow the driver to place the adapter in a safe - * state before a warm reboot occurs. To be really safe, the user - * should close the adapter before shutdown (eg. ifconfig fddi0 down) - * to ensure that the adapter DMA engine is taken off-line. However, - * the current driver code anticipates this problem and always issues - * a soft reset of the adapter at the beginning of driver initialization. - * A future driver enhancement in this area may occur in 2.1.X where - * Alan indicated that a shutdown handler may be implemented. - * - * Interrupt Service Routine - - * The driver supports shared interrupts, so the ISR is registered for - * each board with the appropriate flag and the pointer to that board's - * device structure. This provides the context during interrupt - * processing to support shared interrupts and multiple boards. - * - * Interrupt enabling/disabling can occur at many levels. At the host - * end, you can disable system interrupts, or disable interrupts at the - * PIC (on Intel systems). Across the bus, both EISA and PCI adapters - * have a bus-logic chip interrupt enable/disable as well as a DMA - * controller interrupt enable/disable. - * - * The driver currently enables and disables adapter interrupts at the - * bus-logic chip and assumes that Linux will take care of clearing or - * acknowledging any host-based interrupt chips. - * - * Control Functions - - * Control functions are those used to support functions such as adding - * or deleting multicast addresses, enabling or disabling packet - * reception filters, or other custom/proprietary commands. Presently, - * the driver supports the "get statistics", "set multicast list", and - * "set mac address" functions defined by Linux. A list of possible - * enhancements include: - * - * - Custom ioctl interface for executing port interface commands - * - Custom ioctl interface for adding unicast addresses to - * adapter CAM (to support bridge functions). - * - Custom ioctl interface for supporting firmware upgrades. - * - * Hardware (port interface) Support Routines - - * The driver function names that start with "dfx_hw_" represent - * low-level port interface routines that are called frequently. They - * include issuing a DMA or port control command to the adapter, - * resetting the adapter, or reading the adapter state. Since the - * driver initialization and run-time code must make calls into the - * port interface, these routines were written to be as generic and - * usable as possible. - * - * Receive Path - - * The adapter DMA engine supports a 256 entry receive descriptor block - * of which up to 255 entries can be used at any given time. The - * architecture is a standard producer, consumer, completion model in - * which the driver "produces" receive buffers to the adapter, the - * adapter "consumes" the receive buffers by DMAing incoming packet data, - * and the driver "completes" the receive buffers by servicing the - * incoming packet, then "produces" a new buffer and starts the cycle - * again. Receive buffers can be fragmented in up to 16 fragments - * (descriptor entries). For simplicity, this driver posts - * single-fragment receive buffers of 4608 bytes, then allocates a - * sk_buff, copies the data, then reposts the buffer. To reduce CPU - * utilization, a better approach would be to pass up the receive - * buffer (no extra copy) then allocate and post a replacement buffer. - * This is a performance enhancement that should be looked into at - * some point. - * - * Transmit Path - - * Like the receive path, the adapter DMA engine supports a 256 entry - * transmit descriptor block of which up to 255 entries can be used at - * any given time. Transmit buffers can be fragmented in up to 255 - * fragments (descriptor entries). This driver always posts one - * fragment per transmit packet request. - * - * The fragment contains the entire packet from FC to end of data. - * Before posting the buffer to the adapter, the driver sets a three-byte - * packet request header (PRH) which is required by the Motorola MAC chip - * used on the adapters. The PRH tells the MAC the type of token to - * receive/send, whether or not to generate and append the CRC, whether - * synchronous or asynchronous framing is used, etc. Since the PRH - * definition is not necessarily consistent across all FDDI chipsets, - * the driver, rather than the common FDDI packet handler routines, - * sets these bytes. - * - * To reduce the amount of descriptor fetches needed per transmit request, - * the driver takes advantage of the fact that there are at least three - * bytes available before the skb->data field on the outgoing transmit - * request. This is guaranteed by having fddi_setup() in net_init.c set - * dev->hard_header_len to 24 bytes. 21 bytes accounts for the largest - * header in an 802.2 SNAP frame. The other 3 bytes are the extra "pad" - * bytes which we'll use to store the PRH. - * - * There's a subtle advantage to adding these pad bytes to the - * hard_header_len, it ensures that the data portion of the packet for - * an 802.2 SNAP frame is longword aligned. Other FDDI driver - * implementations may not need the extra padding and can start copying - * or DMAing directly from the FC byte which starts at skb->data. Should - * another driver implementation need ADDITIONAL padding, the net_init.c - * module should be updated and dev->hard_header_len should be increased. - * NOTE: To maintain the alignment on the data portion of the packet, - * dev->hard_header_len should always be evenly divisible by 4 and at - * least 24 bytes in size. - * - * Modification History: - * Date Name Description - * 16-Aug-96 LVS Created. - * 20-Aug-96 LVS Updated dfx_probe so that version information - * string is only displayed if 1 or more cards are - * found. Changed dfx_rcv_queue_process to copy - * 3 NULL bytes before FC to ensure that data is - * longword aligned in receive buffer. - * 09-Sep-96 LVS Updated dfx_ctl_set_multicast_list to enable - * LLC group promiscuous mode if multicast list - * is too large. LLC individual/group promiscuous - * mode is now disabled if IFF_PROMISC flag not set. - * dfx_xmt_queue_pkt no longer checks for NULL skb - * on Alan Cox recommendation. Added node address - * override support. - * 12-Sep-96 LVS Reset current address to factory address during - * device open. Updated transmit path to post a - * single fragment which includes PRH->end of data. - * Mar 2000 AC Did various cleanups for 2.3.x - * Jun 2000 jgarzik PCI and resource alloc cleanups - * Jul 2000 tjeerd Much cleanup and some bug fixes - * Sep 2000 tjeerd Fix leak on unload, cosmetic code cleanup - * Feb 2001 Skb allocation fixes - * Feb 2001 davej PCI enable cleanups. - * 04 Aug 2003 macro Converted to the DMA API. - * 14 Aug 2004 macro Fix device names reported. - * 14 Jun 2005 macro Use irqreturn_t. - * 23 Oct 2006 macro Big-endian host support. - * 14 Dec 2006 macro TURBOchannel support. - */ - -/* Include files */ -#include <linux/bitops.h> -#include <linux/compiler.h> -#include <linux/delay.h> -#include <linux/dma-mapping.h> -#include <linux/eisa.h> -#include <linux/errno.h> -#include <linux/fddidevice.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/pci.h> -#include <linux/skbuff.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/tc.h> - -#include <asm/byteorder.h> -#include <asm/io.h> - -#include "defxx.h" - -/* Version information string should be updated prior to each new release! */ -#define DRV_NAME "defxx" -#define DRV_VERSION "v1.10" -#define DRV_RELDATE "2006/12/14" - -static char version[] __devinitdata = - DRV_NAME ": " DRV_VERSION " " DRV_RELDATE - " Lawrence V. Stefani and others\n"; - -#define DYNAMIC_BUFFERS 1 - -#define SKBUFF_RX_COPYBREAK 200 -/* - * NEW_SKB_SIZE = PI_RCV_DATA_K_SIZE_MAX+128 to allow 128 byte - * alignment for compatibility with old EISA boards. - */ -#define NEW_SKB_SIZE (PI_RCV_DATA_K_SIZE_MAX+128) - -#ifdef CONFIG_PCI -#define DFX_BUS_PCI(dev) (dev->bus == &pci_bus_type) -#else -#define DFX_BUS_PCI(dev) 0 -#endif - -#ifdef CONFIG_EISA -#define DFX_BUS_EISA(dev) (dev->bus == &eisa_bus_type) -#else -#define DFX_BUS_EISA(dev) 0 -#endif - -#ifdef CONFIG_TC -#define DFX_BUS_TC(dev) (dev->bus == &tc_bus_type) -#else -#define DFX_BUS_TC(dev) 0 -#endif - -#ifdef CONFIG_DEFXX_MMIO -#define DFX_MMIO 1 -#else -#define DFX_MMIO 0 -#endif - -/* Define module-wide (static) routines */ - -static void dfx_bus_init(struct net_device *dev); -static void dfx_bus_uninit(struct net_device *dev); -static void dfx_bus_config_check(DFX_board_t *bp); - -static int dfx_driver_init(struct net_device *dev, - const char *print_name, - resource_size_t bar_start); -static int dfx_adap_init(DFX_board_t *bp, int get_buffers); - -static int dfx_open(struct net_device *dev); -static int dfx_close(struct net_device *dev); - -static void dfx_int_pr_halt_id(DFX_board_t *bp); -static void dfx_int_type_0_process(DFX_board_t *bp); -static void dfx_int_common(struct net_device *dev); -static irqreturn_t dfx_interrupt(int irq, void *dev_id); - -static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev); -static void dfx_ctl_set_multicast_list(struct net_device *dev); -static int dfx_ctl_set_mac_address(struct net_device *dev, void *addr); -static int dfx_ctl_update_cam(DFX_board_t *bp); -static int dfx_ctl_update_filters(DFX_board_t *bp); - -static int dfx_hw_dma_cmd_req(DFX_board_t *bp); -static int dfx_hw_port_ctrl_req(DFX_board_t *bp, PI_UINT32 command, PI_UINT32 data_a, PI_UINT32 data_b, PI_UINT32 *host_data); -static void dfx_hw_adap_reset(DFX_board_t *bp, PI_UINT32 type); -static int dfx_hw_adap_state_rd(DFX_board_t *bp); -static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type); - -static int dfx_rcv_init(DFX_board_t *bp, int get_buffers); -static void dfx_rcv_queue_process(DFX_board_t *bp); -static void dfx_rcv_flush(DFX_board_t *bp); - -static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb, - struct net_device *dev); -static int dfx_xmt_done(DFX_board_t *bp); -static void dfx_xmt_flush(DFX_board_t *bp); - -/* Define module-wide (static) variables */ - -static struct pci_driver dfx_pci_driver; -static struct eisa_driver dfx_eisa_driver; -static struct tc_driver dfx_tc_driver; - - -/* - * ======================= - * = dfx_port_write_long = - * = dfx_port_read_long = - * ======================= - * - * Overview: - * Routines for reading and writing values from/to adapter - * - * Returns: - * None - * - * Arguments: - * bp - pointer to board information - * offset - register offset from base I/O address - * data - for dfx_port_write_long, this is a value to write; - * for dfx_port_read_long, this is a pointer to store - * the read value - * - * Functional Description: - * These routines perform the correct operation to read or write - * the adapter register. - * - * EISA port block base addresses are based on the slot number in which the - * controller is installed. For example, if the EISA controller is installed - * in slot 4, the port block base address is 0x4000. If the controller is - * installed in slot 2, the port block base address is 0x2000, and so on. - * This port block can be used to access PDQ, ESIC, and DEFEA on-board - * registers using the register offsets defined in DEFXX.H. - * - * PCI port block base addresses are assigned by the PCI BIOS or system - * firmware. There is one 128 byte port block which can be accessed. It - * allows for I/O mapping of both PDQ and PFI registers using the register - * offsets defined in DEFXX.H. - * - * Return Codes: - * None - * - * Assumptions: - * bp->base is a valid base I/O address for this adapter. - * offset is a valid register offset for this adapter. - * - * Side Effects: - * Rather than produce macros for these functions, these routines - * are defined using "inline" to ensure that the compiler will - * generate inline code and not waste a procedure call and return. - * This provides all the benefits of macros, but with the - * advantage of strict data type checking. - */ - -static inline void dfx_writel(DFX_board_t *bp, int offset, u32 data) -{ - writel(data, bp->base.mem + offset); - mb(); -} - -static inline void dfx_outl(DFX_board_t *bp, int offset, u32 data) -{ - outl(data, bp->base.port + offset); -} - -static void dfx_port_write_long(DFX_board_t *bp, int offset, u32 data) -{ - struct device __maybe_unused *bdev = bp->bus_dev; - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - - if (dfx_use_mmio) - dfx_writel(bp, offset, data); - else - dfx_outl(bp, offset, data); -} - - -static inline void dfx_readl(DFX_board_t *bp, int offset, u32 *data) -{ - mb(); - *data = readl(bp->base.mem + offset); -} - -static inline void dfx_inl(DFX_board_t *bp, int offset, u32 *data) -{ - *data = inl(bp->base.port + offset); -} - -static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data) -{ - struct device __maybe_unused *bdev = bp->bus_dev; - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - - if (dfx_use_mmio) - dfx_readl(bp, offset, data); - else - dfx_inl(bp, offset, data); -} - - -/* - * ================ - * = dfx_get_bars = - * ================ - * - * Overview: - * Retrieves the address range used to access control and status - * registers. - * - * Returns: - * None - * - * Arguments: - * bdev - pointer to device information - * bar_start - pointer to store the start address - * bar_len - pointer to store the length of the area - * - * Assumptions: - * I am sure there are some. - * - * Side Effects: - * None - */ -static void dfx_get_bars(struct device *bdev, - resource_size_t *bar_start, resource_size_t *bar_len) -{ - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - - if (dfx_bus_pci) { - int num = dfx_use_mmio ? 0 : 1; - - *bar_start = pci_resource_start(to_pci_dev(bdev), num); - *bar_len = pci_resource_len(to_pci_dev(bdev), num); - } - if (dfx_bus_eisa) { - unsigned long base_addr = to_eisa_device(bdev)->base_addr; - resource_size_t bar; - - if (dfx_use_mmio) { - bar = inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_2); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_1); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_CMP_0); - bar <<= 16; - *bar_start = bar; - bar = inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_2); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_1); - bar <<= 8; - bar |= inb(base_addr + PI_ESIC_K_MEM_ADD_MASK_0); - bar <<= 16; - *bar_len = (bar | PI_MEM_ADD_MASK_M) + 1; - } else { - *bar_start = base_addr; - *bar_len = PI_ESIC_K_CSR_IO_LEN; - } - } - if (dfx_bus_tc) { - *bar_start = to_tc_dev(bdev)->resource.start + - PI_TC_K_CSR_OFFSET; - *bar_len = PI_TC_K_CSR_LEN; - } -} - -static const struct net_device_ops dfx_netdev_ops = { - .ndo_open = dfx_open, - .ndo_stop = dfx_close, - .ndo_start_xmit = dfx_xmt_queue_pkt, - .ndo_get_stats = dfx_ctl_get_stats, - .ndo_set_rx_mode = dfx_ctl_set_multicast_list, - .ndo_set_mac_address = dfx_ctl_set_mac_address, -}; - -/* - * ================ - * = dfx_register = - * ================ - * - * Overview: - * Initializes a supported FDDI controller - * - * Returns: - * Condition code - * - * Arguments: - * bdev - pointer to device information - * - * Functional Description: - * - * Return Codes: - * 0 - This device (fddi0, fddi1, etc) configured successfully - * -EBUSY - Failed to get resources, or dfx_driver_init failed. - * - * Assumptions: - * It compiles so it should work :-( (PCI cards do :-) - * - * Side Effects: - * Device structures for FDDI adapters (fddi0, fddi1, etc) are - * initialized and the board resources are read and stored in - * the device structure. - */ -static int __devinit dfx_register(struct device *bdev) -{ - static int version_disp; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - const char *print_name = dev_name(bdev); - struct net_device *dev; - DFX_board_t *bp; /* board pointer */ - resource_size_t bar_start = 0; /* pointer to port */ - resource_size_t bar_len = 0; /* resource length */ - int alloc_size; /* total buffer size used */ - struct resource *region; - int err = 0; - - if (!version_disp) { /* display version info if adapter is found */ - version_disp = 1; /* set display flag to TRUE so that */ - printk(version); /* we only display this string ONCE */ - } - - dev = alloc_fddidev(sizeof(*bp)); - if (!dev) { - printk(KERN_ERR "%s: Unable to allocate fddidev, aborting\n", - print_name); - return -ENOMEM; - } - - /* Enable PCI device. */ - if (dfx_bus_pci && pci_enable_device(to_pci_dev(bdev))) { - printk(KERN_ERR "%s: Cannot enable PCI device, aborting\n", - print_name); - goto err_out; - } - - SET_NETDEV_DEV(dev, bdev); - - bp = netdev_priv(dev); - bp->bus_dev = bdev; - dev_set_drvdata(bdev, dev); - - dfx_get_bars(bdev, &bar_start, &bar_len); - - if (dfx_use_mmio) - region = request_mem_region(bar_start, bar_len, print_name); - else - region = request_region(bar_start, bar_len, print_name); - if (!region) { - printk(KERN_ERR "%s: Cannot reserve I/O resource " - "0x%lx @ 0x%lx, aborting\n", - print_name, (long)bar_len, (long)bar_start); - err = -EBUSY; - goto err_out_disable; - } - - /* Set up I/O base address. */ - if (dfx_use_mmio) { - bp->base.mem = ioremap_nocache(bar_start, bar_len); - if (!bp->base.mem) { - printk(KERN_ERR "%s: Cannot map MMIO\n", print_name); - err = -ENOMEM; - goto err_out_region; - } - } else { - bp->base.port = bar_start; - dev->base_addr = bar_start; - } - - /* Initialize new device structure */ - dev->netdev_ops = &dfx_netdev_ops; - - if (dfx_bus_pci) - pci_set_master(to_pci_dev(bdev)); - - if (dfx_driver_init(dev, print_name, bar_start) != DFX_K_SUCCESS) { - err = -ENODEV; - goto err_out_unmap; - } - - err = register_netdev(dev); - if (err) - goto err_out_kfree; - - printk("%s: registered as %s\n", print_name, dev->name); - return 0; - -err_out_kfree: - alloc_size = sizeof(PI_DESCR_BLOCK) + - PI_CMD_REQ_K_SIZE_MAX + PI_CMD_RSP_K_SIZE_MAX + -#ifndef DYNAMIC_BUFFERS - (bp->rcv_bufs_to_post * PI_RCV_DATA_K_SIZE_MAX) + -#endif - sizeof(PI_CONSUMER_BLOCK) + - (PI_ALIGN_K_DESC_BLK - 1); - if (bp->kmalloced) - dma_free_coherent(bdev, alloc_size, - bp->kmalloced, bp->kmalloced_dma); - -err_out_unmap: - if (dfx_use_mmio) - iounmap(bp->base.mem); - -err_out_region: - if (dfx_use_mmio) - release_mem_region(bar_start, bar_len); - else - release_region(bar_start, bar_len); - -err_out_disable: - if (dfx_bus_pci) - pci_disable_device(to_pci_dev(bdev)); - -err_out: - free_netdev(dev); - return err; -} - - -/* - * ================ - * = dfx_bus_init = - * ================ - * - * Overview: - * Initializes the bus-specific controller logic. - * - * Returns: - * None - * - * Arguments: - * dev - pointer to device information - * - * Functional Description: - * Determine and save adapter IRQ in device table, - * then perform bus-specific logic initialization. - * - * Return Codes: - * None - * - * Assumptions: - * bp->base has already been set with the proper - * base I/O address for this device. - * - * Side Effects: - * Interrupts are enabled at the adapter bus-specific logic. - * Note: Interrupts at the DMA engine (PDQ chip) are not - * enabled yet. - */ - -static void __devinit dfx_bus_init(struct net_device *dev) -{ - DFX_board_t *bp = netdev_priv(dev); - struct device *bdev = bp->bus_dev; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - u8 val; - - DBG_printk("In dfx_bus_init...\n"); - - /* Initialize a pointer back to the net_device struct */ - bp->dev = dev; - - /* Initialize adapter based on bus type */ - - if (dfx_bus_tc) - dev->irq = to_tc_dev(bdev)->interrupt; - if (dfx_bus_eisa) { - unsigned long base_addr = to_eisa_device(bdev)->base_addr; - - /* Get the interrupt level from the ESIC chip. */ - val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); - val &= PI_CONFIG_STAT_0_M_IRQ; - val >>= PI_CONFIG_STAT_0_V_IRQ; - - switch (val) { - case PI_CONFIG_STAT_0_IRQ_K_9: - dev->irq = 9; - break; - - case PI_CONFIG_STAT_0_IRQ_K_10: - dev->irq = 10; - break; - - case PI_CONFIG_STAT_0_IRQ_K_11: - dev->irq = 11; - break; - - case PI_CONFIG_STAT_0_IRQ_K_15: - dev->irq = 15; - break; - } - - /* - * Enable memory decoding (MEMCS0) and/or port decoding - * (IOCS1/IOCS0) as appropriate in Function Control - * Register. One of the port chip selects seems to be - * used for the Burst Holdoff register, but this bit of - * documentation is missing and as yet it has not been - * determined which of the two. This is also the reason - * the size of the decoded port range is twice as large - * as one required by the PDQ. - */ - - /* Set the decode range of the board. */ - val = ((bp->base.port >> 12) << PI_IO_CMP_V_SLOT); - outb(base_addr + PI_ESIC_K_IO_ADD_CMP_0_1, val); - outb(base_addr + PI_ESIC_K_IO_ADD_CMP_0_0, 0); - outb(base_addr + PI_ESIC_K_IO_ADD_CMP_1_1, val); - outb(base_addr + PI_ESIC_K_IO_ADD_CMP_1_0, 0); - val = PI_ESIC_K_CSR_IO_LEN - 1; - outb(base_addr + PI_ESIC_K_IO_ADD_MASK_0_1, (val >> 8) & 0xff); - outb(base_addr + PI_ESIC_K_IO_ADD_MASK_0_0, val & 0xff); - outb(base_addr + PI_ESIC_K_IO_ADD_MASK_1_1, (val >> 8) & 0xff); - outb(base_addr + PI_ESIC_K_IO_ADD_MASK_1_0, val & 0xff); - - /* Enable the decoders. */ - val = PI_FUNCTION_CNTRL_M_IOCS1 | PI_FUNCTION_CNTRL_M_IOCS0; - if (dfx_use_mmio) - val |= PI_FUNCTION_CNTRL_M_MEMCS0; - outb(base_addr + PI_ESIC_K_FUNCTION_CNTRL, val); - - /* - * Enable access to the rest of the module - * (including PDQ and packet memory). - */ - val = PI_SLOT_CNTRL_M_ENB; - outb(base_addr + PI_ESIC_K_SLOT_CNTRL, val); - - /* - * Map PDQ registers into memory or port space. This is - * done with a bit in the Burst Holdoff register. - */ - val = inb(base_addr + PI_DEFEA_K_BURST_HOLDOFF); - if (dfx_use_mmio) - val |= PI_BURST_HOLDOFF_V_MEM_MAP; - else - val &= ~PI_BURST_HOLDOFF_V_MEM_MAP; - outb(base_addr + PI_DEFEA_K_BURST_HOLDOFF, val); - - /* Enable interrupts at EISA bus interface chip (ESIC) */ - val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); - val |= PI_CONFIG_STAT_0_M_INT_ENB; - outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, val); - } - if (dfx_bus_pci) { - struct pci_dev *pdev = to_pci_dev(bdev); - - /* Get the interrupt level from the PCI Configuration Table */ - - dev->irq = pdev->irq; - - /* Check Latency Timer and set if less than minimal */ - - pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &val); - if (val < PFI_K_LAT_TIMER_MIN) { - val = PFI_K_LAT_TIMER_DEF; - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, val); - } - - /* Enable interrupts at PCI bus interface chip (PFI) */ - val = PFI_MODE_M_PDQ_INT_ENB | PFI_MODE_M_DMA_ENB; - dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, val); - } -} - -/* - * ================== - * = dfx_bus_uninit = - * ================== - * - * Overview: - * Uninitializes the bus-specific controller logic. - * - * Returns: - * None - * - * Arguments: - * dev - pointer to device information - * - * Functional Description: - * Perform bus-specific logic uninitialization. - * - * Return Codes: - * None - * - * Assumptions: - * bp->base has already been set with the proper - * base I/O address for this device. - * - * Side Effects: - * Interrupts are disabled at the adapter bus-specific logic. - */ - -static void __devexit dfx_bus_uninit(struct net_device *dev) -{ - DFX_board_t *bp = netdev_priv(dev); - struct device *bdev = bp->bus_dev; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - u8 val; - - DBG_printk("In dfx_bus_uninit...\n"); - - /* Uninitialize adapter based on bus type */ - - if (dfx_bus_eisa) { - unsigned long base_addr = to_eisa_device(bdev)->base_addr; - - /* Disable interrupts at EISA bus interface chip (ESIC) */ - val = inb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0); - val &= ~PI_CONFIG_STAT_0_M_INT_ENB; - outb(base_addr + PI_ESIC_K_IO_CONFIG_STAT_0, val); - } - if (dfx_bus_pci) { - /* Disable interrupts at PCI bus interface chip (PFI) */ - dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, 0); - } -} - - -/* - * ======================== - * = dfx_bus_config_check = - * ======================== - * - * Overview: - * Checks the configuration (burst size, full-duplex, etc.) If any parameters - * are illegal, then this routine will set new defaults. - * - * Returns: - * None - * - * Arguments: - * bp - pointer to board information - * - * Functional Description: - * For Revision 1 FDDI EISA, Revision 2 or later FDDI EISA with rev E or later - * PDQ, and all FDDI PCI controllers, all values are legal. - * - * Return Codes: - * None - * - * Assumptions: - * dfx_adap_init has NOT been called yet so burst size and other items have - * not been set. - * - * Side Effects: - * None - */ - -static void __devinit dfx_bus_config_check(DFX_board_t *bp) -{ - struct device __maybe_unused *bdev = bp->bus_dev; - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - int status; /* return code from adapter port control call */ - u32 host_data; /* LW data returned from port control call */ - - DBG_printk("In dfx_bus_config_check...\n"); - - /* Configuration check only valid for EISA adapter */ - - if (dfx_bus_eisa) { - /* - * First check if revision 2 EISA controller. Rev. 1 cards used - * PDQ revision B, so no workaround needed in this case. Rev. 3 - * cards used PDQ revision E, so no workaround needed in this - * case, either. Only Rev. 2 cards used either Rev. D or E - * chips, so we must verify the chip revision on Rev. 2 cards. - */ - if (to_eisa_device(bdev)->id.driver_data == DEFEA_PROD_ID_2) { - /* - * Revision 2 FDDI EISA controller found, - * so let's check PDQ revision of adapter. - */ - status = dfx_hw_port_ctrl_req(bp, - PI_PCTRL_M_SUB_CMD, - PI_SUB_CMD_K_PDQ_REV_GET, - 0, - &host_data); - if ((status != DFX_K_SUCCESS) || (host_data == 2)) - { - /* - * Either we couldn't determine the PDQ revision, or - * we determined that it is at revision D. In either case, - * we need to implement the workaround. - */ - - /* Ensure that the burst size is set to 8 longwords or less */ - - switch (bp->burst_size) - { - case PI_PDATA_B_DMA_BURST_SIZE_32: - case PI_PDATA_B_DMA_BURST_SIZE_16: - bp->burst_size = PI_PDATA_B_DMA_BURST_SIZE_8; - break; - - default: - break; - } - - /* Ensure that full-duplex mode is not enabled */ - - bp->full_duplex_enb = PI_SNMP_K_FALSE; - } - } - } - } - - -/* - * =================== - * = dfx_driver_init = - * =================== - * - * Overview: - * Initializes remaining adapter board structure information - * and makes sure adapter is in a safe state prior to dfx_open(). - * - * Returns: - * Condition code - * - * Arguments: - * dev - pointer to device information - * print_name - printable device name - * - * Functional Description: - * This function allocates additional resources such as the host memory - * blocks needed by the adapter (eg. descriptor and consumer blocks). - * Remaining bus initialization steps are also completed. The adapter - * is also reset so that it is in the DMA_UNAVAILABLE state. The OS - * must call dfx_open() to open the adapter and bring it on-line. - * - * Return Codes: - * DFX_K_SUCCESS - initialization succeeded - * DFX_K_FAILURE - initialization failed - could not allocate memory - * or read adapter MAC address - * - * Assumptions: - * Memory allocated from pci_alloc_consistent() call is physically - * contiguous, locked memory. - * - * Side Effects: - * Adapter is reset and should be in DMA_UNAVAILABLE state before - * returning from this routine. - */ - -static int __devinit dfx_driver_init(struct net_device *dev, - const char *print_name, - resource_size_t bar_start) -{ - DFX_board_t *bp = netdev_priv(dev); - struct device *bdev = bp->bus_dev; - int dfx_bus_pci = DFX_BUS_PCI(bdev); - int dfx_bus_eisa = DFX_BUS_EISA(bdev); - int dfx_bus_tc = DFX_BUS_TC(bdev); - int dfx_use_mmio = DFX_MMIO || dfx_bus_tc; - int alloc_size; /* total buffer size needed */ - char *top_v, *curr_v; /* virtual addrs into memory block */ - dma_addr_t top_p, curr_p; /* physical addrs into memory block */ - u32 data; /* host data register value */ - __le32 le32; - char *board_name = NULL; - - DBG_printk("In dfx_driver_init...\n"); - - /* Initialize bus-specific hardware registers */ - - dfx_bus_init(dev); - - /* - * Initialize default values for configurable parameters - * - * Note: All of these parameters are ones that a user may - * want to customize. It'd be nice to break these - * out into Space.c or someplace else that's more - * accessible/understandable than this file. - */ - - bp->full_duplex_enb = PI_SNMP_K_FALSE; - bp->req_ttrt = 8 * 12500; /* 8ms in 80 nanosec units */ - bp->burst_size = PI_PDATA_B_DMA_BURST_SIZE_DEF; - bp->rcv_bufs_to_post = RCV_BUFS_DEF; - - /* - * Ensure that HW configuration is OK - * - * Note: Depending on the hardware revision, we may need to modify - * some of the configurable parameters to workaround hardware - * limitations. We'll perform this configuration check AFTER - * setting the parameters to their default values. - */ - - dfx_bus_config_check(bp); - - /* Disable PDQ interrupts first */ - - dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_DISABLE_ALL_INTS); - - /* Place adapter in DMA_UNAVAILABLE state by resetting adapter */ - - (void) dfx_hw_dma_uninit(bp, PI_PDATA_A_RESET_M_SKIP_ST); - - /* Read the factory MAC address from the adapter then save it */ - - if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_LO, 0, - &data) != DFX_K_SUCCESS) { - printk("%s: Could not read adapter factory MAC address!\n", - print_name); - return DFX_K_FAILURE; - } - le32 = cpu_to_le32(data); - memcpy(&bp->factory_mac_addr[0], &le32, sizeof(u32)); - - if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_HI, 0, - &data) != DFX_K_SUCCESS) { - printk("%s: Could not read adapter factory MAC address!\n", - print_name); - return DFX_K_FAILURE; - } - le32 = cpu_to_le32(data); - memcpy(&bp->factory_mac_addr[4], &le32, sizeof(u16)); - - /* - * Set current address to factory address - * - * Note: Node address override support is handled through - * dfx_ctl_set_mac_address. - */ - - memcpy(dev->dev_addr, bp->factory_mac_addr, FDDI_K_ALEN); - if (dfx_bus_tc) - board_name = "DEFTA"; - if (dfx_bus_eisa) - board_name = "DEFEA"; - if (dfx_bus_pci) - board_name = "DEFPA"; - pr_info("%s: %s at %saddr = 0x%llx, IRQ = %d, Hardware addr = %pMF\n", - print_name, board_name, dfx_use_mmio ? "" : "I/O ", - (long long)bar_start, dev->irq, dev-> |