aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/defxx.c
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-07-31 00:06:29 -0700
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-08-27 00:58:13 -0700
commit33f810b2036f13f1b123062a9e5c1794d400ce81 (patch)
tree370b55026f4bd856e96842f86af631ca2bab3da2 /drivers/net/defxx.c
parent3cd0999d134235d64b175edd2eb1d46ebc97b377 (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.c3739
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->