linux/drivers/net/ethernet/3com/3c59x.c

/* EtherLinkXL.c: A 3Com EtherLink PCI III/XL ethernet driver for linux. */
/*
	Written 1996-1999 by Donald Becker.

	This software may be used and distributed according to the terms
	of the GNU General Public License, incorporated herein by reference.

	This driver is for the 3Com "Vortex" and "Boomerang" series ethercards.
	Members of the series include Fast EtherLink 3c590/3c592/3c595/3c597
	and the EtherLink XL 3c900 and 3c905 cards.

	Problem reports and questions should be directed to
	[email protected]

	The author may be reached as [email protected], or C/O
	Scyld Computing Corporation
	410 Severn Ave., Suite 210
	Annapolis MD 21403

*/

/*
 * FIXME: This driver _could_ support MTU changing, but doesn't.  See Don's hamachi.c implementation
 * as well as other drivers
 *
 * NOTE: If you make 'vortex_debug' a constant (#define vortex_debug 0) the driver shrinks by 2k
 * due to dead code elimination.  There will be some performance benefits from this due to
 * elimination of all the tests and reduced cache footprint.
 */


#define DRV_NAME



/* A few values that may be tweaked. */
/* Keep the ring sizes a power of two for efficiency. */
#define TX_RING_SIZE
#define RX_RING_SIZE
#define PKT_BUF_SZ

/* "Knobs" that adjust features and parameters. */
/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
   Setting to > 1512 effectively disables this feature. */
#ifndef __arm__
static int rx_copybreak =;
#else
/* ARM systems perform better by disregarding the bus-master
   transfer capability of these cards. -- rmk */
static int rx_copybreak = 1513;
#endif
/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
static const int mtu =;
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static int max_interrupt_work =;
/* Tx timeout interval (millisecs) */
static int watchdog =;

/* Allow aggregation of Tx interrupts.  Saves CPU load at the cost
 * of possible Tx stalls if the system is blocking interrupts
 * somewhere else.  Undefine this to disable.
 */
#define tx_interrupt_mitigation

/* Put out somewhat more debugging messages. (0: no msg, 1 minimal .. 6). */
#define vortex_debug
#ifdef VORTEX_DEBUG
static int vortex_debug = VORTEX_DEBUG;
#else
static int vortex_debug =;
#endif

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/mii.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/highmem.h>
#include <linux/eisa.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
#include <linux/gfp.h>
#include <asm/irq.h>			/* For nr_irqs only. */
#include <asm/io.h>
#include <linux/uaccess.h>

/* Kernel compatibility defines, some common to David Hinds' PCMCIA package.
   This is only in the support-all-kernels source code. */

#define RUN_AT(x)

#include <linux/delay.h>


static const char version[] =;

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();


/* Operational parameter that usually are not changed. */

/* The Vortex size is twice that of the original EtherLinkIII series: the
   runtime register window, window 1, is now always mapped in.
   The Boomerang size is twice as large as the Vortex -- it has additional
   bus master control registers. */
#define VORTEX_TOTAL_SIZE
#define BOOMERANG_TOTAL_SIZE

/* Set iff a MII transceiver on any interface requires mdio preamble.
   This only set with the original DP83840 on older 3c905 boards, so the extra
   code size of a per-interface flag is not worthwhile. */
static char mii_preamble_required;

#define PFX



/*
				Theory of Operation

I. Board Compatibility

This device driver is designed for the 3Com FastEtherLink and FastEtherLink
XL, 3Com's PCI to 10/100baseT adapters.  It also works with the 10Mbs
versions of the FastEtherLink cards.  The supported product IDs are
  3c590, 3c592, 3c595, 3c597, 3c900, 3c905

The related ISA 3c515 is supported with a separate driver, 3c515.c, included
with the kernel source or available from
    cesdis.gsfc.nasa.gov:/pub/linux/drivers/3c515.html

II. Board-specific settings

PCI bus devices are configured by the system at boot time, so no jumpers
need to be set on the board.  The system BIOS should be set to assign the
PCI INTA signal to an otherwise unused system IRQ line.

The EEPROM settings for media type and forced-full-duplex are observed.
The EEPROM media type should be left at the default "autoselect" unless using
10base2 or AUI connections which cannot be reliably detected.

III. Driver operation

The 3c59x series use an interface that's very similar to the previous 3c5x9
series.  The primary interface is two programmed-I/O FIFOs, with an
alternate single-contiguous-region bus-master transfer (see next).

The 3c900 "Boomerang" series uses a full-bus-master interface with separate
lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
DEC Tulip and Intel Speedo3.  The first chip version retains a compatible
programmed-I/O interface that has been removed in 'B' and subsequent board
revisions.

One extension that is advertised in a very large font is that the adapters
are capable of being bus masters.  On the Vortex chip this capability was
only for a single contiguous region making it far less useful than the full
bus master capability.  There is a significant performance impact of taking
an extra interrupt or polling for the completion of each transfer, as well
as difficulty sharing the single transfer engine between the transmit and
receive threads.  Using DMA transfers is a win only with large blocks or
with the flawed versions of the Intel Orion motherboard PCI controller.

The Boomerang chip's full-bus-master interface is useful, and has the
currently-unused advantages over other similar chips that queued transmit
packets may be reordered and receive buffer groups are associated with a
single frame.

With full-bus-master support, this driver uses a "RX_COPYBREAK" scheme.
Rather than a fixed intermediate receive buffer, this scheme allocates
full-sized skbuffs as receive buffers.  The value RX_COPYBREAK is used as
the copying breakpoint: it is chosen to trade-off the memory wasted by
passing the full-sized skbuff to the queue layer for all frames vs. the
copying cost of copying a frame to a correctly-sized skbuff.

IIIC. Synchronization
The driver runs as two independent, single-threaded flows of control.  One
is the send-packet routine, which enforces single-threaded use by the
dev->tbusy flag.  The other thread is the interrupt handler, which is single
threaded by the hardware and other software.

IV. Notes

Thanks to Cameron Spitzer and Terry Murphy of 3Com for providing development
3c590, 3c595, and 3c900 boards.
The name "Vortex" is the internal 3Com project name for the PCI ASIC, and
the EISA version is called "Demon".  According to Terry these names come
from rides at the local amusement park.

The new chips support both ethernet (1.5K) and FDDI (4.5K) packet sizes!
This driver only supports ethernet packets because of the skbuff allocation
limit of 4K.
*/

/* This table drives the PCI probe routines.  It's mostly boilerplate in all
   of the drivers, and will likely be provided by some future kernel.
*/
enum pci_flags_bit {};

enum {};

enum vortex_chips {};


/* note: this array directly indexed by above enums, and MUST
 * be kept in sync with both the enums above, and the PCI device
 * table below
 */
static struct vortex_chip_info {} vortex_info_tbl[] =;


static const struct pci_device_id vortex_pci_tbl[] =;
MODULE_DEVICE_TABLE(pci, vortex_pci_tbl);


/* Operational definitions.
   These are not used by other compilation units and thus are not
   exported in a ".h" file.

   First the windows.  There are eight register windows, with the command
   and status registers available in each.
   */
#define EL3_CMD
#define EL3_STATUS

/* The top five bits written to EL3_CMD are a command, the lower
   11 bits are the parameter, if applicable.
   Note that 11 parameters bits was fine for ethernet, but the new chip
   can handle FDDI length frames (~4500 octets) and now parameters count
   32-bit 'Dwords' rather than octets. */

enum vortex_cmd {};

/* The SetRxFilter command accepts the following classes: */
enum RxFilter {};

/* Bits in the general status register. */
enum vortex_status {};

/* Register window 1 offsets, the window used in normal operation.
   On the Vortex this window is always mapped at offsets 0x10-0x1f. */
enum Window1 {};
enum Window0 {};
enum Win0_EEPROM_bits {};
/* EEPROM locations. */
enum eeprom_offset {};

enum Window2 {};
enum Window3 {};

#define BFEXT(value, offset, bitcount)

#define BFINS(lhs, rhs, offset, bitcount)

#define RAM_SIZE(v)
#define RAM_WIDTH(v)
#define RAM_SPEED(v)
#define ROM_SIZE(v)
#define RAM_SPLIT(v)
#define XCVR(v)
#define AUTOSELECT(v)

enum Window4 {};
enum Win4_Media_bits {};
enum Window7 {};
/* Boomerang bus master control registers. */
enum MasterCtrl {};

/* The Rx and Tx descriptor lists.
   Caution Alpha hackers: these types are 32 bits!  Note also the 8 byte
   alignment contraint on tx_ring[] and rx_ring[]. */
#define LAST_FRAG
#define DN_COMPLETE
struct boom_rx_desc {};
/* Values for the Rx status entry. */
enum rx_desc_status {};

#ifdef MAX_SKB_FRAGS
#define DO_ZEROCOPY
#else
#define DO_ZEROCOPY
#endif

struct boom_tx_desc {};

/* Values for the Tx status entry. */
enum tx_desc_status {};

/* Chip features we care about in vp->capabilities, read from the EEPROM. */
enum ChipCaps {};

struct vortex_extra_stats {};

struct vortex_private {};

static void window_set(struct vortex_private *vp, int window)
{}

#define DEFINE_WINDOW_IO(size)
DEFINE_WINDOW_IO()
DEFINE_WINDOW_IO()
DEFINE_WINDOW_IO()

#ifdef CONFIG_PCI
#define DEVICE_PCI(dev)
#else
#define DEVICE_PCI
#endif

#define VORTEX_PCI(vp)

#ifdef CONFIG_EISA
#define DEVICE_EISA(dev)
#else
#define DEVICE_EISA
#endif

#define VORTEX_EISA(vp)

/* The action to take with a media selection timer tick.
   Note that we deviate from the 3Com order by checking 10base2 before AUI.
 */
enum xcvr_types {};

static const struct media_table {} media_tbl[] =;

static struct {} ethtool_stats_keys[] =;

/* number of ETHTOOL_GSTATS u64's */
#define VORTEX_NUM_STATS

static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
				   int chip_idx, int card_idx);
static int vortex_up(struct net_device *dev);
static void vortex_down(struct net_device *dev, int final);
static int vortex_open(struct net_device *dev);
static void mdio_sync(struct vortex_private *vp, int bits);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
static void vortex_timer(struct timer_list *t);
static netdev_tx_t vortex_start_xmit(struct sk_buff *skb,
				     struct net_device *dev);
static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb,
					struct net_device *dev);
static int vortex_rx(struct net_device *dev);
static int boomerang_rx(struct net_device *dev);
static irqreturn_t vortex_boomerang_interrupt(int irq, void *dev_id);
static irqreturn_t _vortex_interrupt(int irq, struct net_device *dev);
static irqreturn_t _boomerang_interrupt(int irq, struct net_device *dev);
static int vortex_close(struct net_device *dev);
static void dump_tx_ring(struct net_device *dev);
static void update_stats(void __iomem *ioaddr, struct net_device *dev);
static struct net_device_stats *vortex_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);
#ifdef CONFIG_PCI
static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
#endif
static void vortex_tx_timeout(struct net_device *dev, unsigned int txqueue);
static void acpi_set_WOL(struct net_device *dev);
static const struct ethtool_ops vortex_ethtool_ops;
static void set_8021q_mode(struct net_device *dev, int enable);

/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
/* Option count limit only -- unlimited interfaces are supported. */
#define MAX_UNITS
static int options[MAX_UNITS] =;
static int full_duplex[MAX_UNITS] =;
static int hw_checksums[MAX_UNITS] =;
static int flow_ctrl[MAX_UNITS] =;
static int enable_wol[MAX_UNITS] =;
static int use_mmio[MAX_UNITS] =;
static int global_options =;
static int global_full_duplex =;
static int global_enable_wol =;
static int global_use_mmio =;

/* Variables to work-around the Compaq PCI BIOS32 problem. */
static int compaq_ioaddr, compaq_irq, compaq_device_id =;
static struct net_device *compaq_net_device;

static int vortex_cards_found;

module_param(debug, int, 0);
module_param(global_options, int, 0);
module_param_array();
module_param(global_full_duplex, int, 0);
module_param_array();
module_param_array();
module_param_array();
module_param(global_enable_wol, int, 0);
module_param_array();
module_param(rx_copybreak, int, 0);
module_param(max_interrupt_work, int, 0);
module_param_hw(compaq_ioaddr, int, ioport, 0);
module_param_hw(compaq_irq, int, irq, 0);
module_param(compaq_device_id, int, 0);
module_param(watchdog, int, 0);
module_param(global_use_mmio, int, 0);
module_param_array();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();

#ifdef CONFIG_NET_POLL_CONTROLLER
static void poll_vortex(struct net_device *dev)
{}
#endif

#ifdef CONFIG_PM

static int vortex_suspend(struct device *dev)
{}

static int vortex_resume(struct device *dev)
{}

static const struct dev_pm_ops vortex_pm_ops =;

#define VORTEX_PM_OPS

#else /* !CONFIG_PM */

#define VORTEX_PM_OPS

#endif /* !CONFIG_PM */

#ifdef CONFIG_EISA
static const struct eisa_device_id vortex_eisa_ids[] =;
MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);

static int vortex_eisa_probe(struct device *device)
{}

static int vortex_eisa_remove(struct device *device)
{}

static struct eisa_driver vortex_eisa_driver =;

#endif /* CONFIG_EISA */

/* returns count found (>= 0), or negative on error */
static int __init vortex_eisa_init(void)
{}

/* returns count (>= 0), or negative on error */
static int vortex_init_one(struct pci_dev *pdev,
			   const struct pci_device_id *ent)
{}

static const struct net_device_ops boomrang_netdev_ops =;

static const struct net_device_ops vortex_netdev_ops =;

/*
 * Start up the PCI/EISA device which is described by *gendev.
 * Return 0 on success.
 *
 * NOTE: pdev can be NULL, for the case of a Compaq device
 */
static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
			 int chip_idx, int card_idx)
{}

static void
issue_and_wait(struct net_device *dev, int cmd)
{}

static void
vortex_set_duplex(struct net_device *dev)
{}

static void vortex_check_media(struct net_device *dev, unsigned int init)
{}

static int
vortex_up(struct net_device *dev)
{}

static int
vortex_open(struct net_device *dev)
{}

static void
vortex_timer(struct timer_list *t)
{}

static void vortex_tx_timeout(struct net_device *dev, unsigned int txqueue)
{}

/*
 * Handle uncommon interrupt sources.  This is a separate routine to minimize
 * the cache impact.
 */
static void
vortex_error(struct net_device *dev, int status)
{}

static netdev_tx_t
vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static netdev_tx_t
boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
{}

/* The interrupt handler does all of the Rx thread work and cleans up
   after the Tx thread. */

/*
 * This is the ISR for the vortex series chips.
 * full_bus_master_tx == 0 && full_bus_master_rx == 0
 */

static irqreturn_t
_vortex_interrupt(int irq, struct net_device *dev)
{}

/*
 * This is the ISR for the boomerang series chips.
 * full_bus_master_tx == 1 && full_bus_master_rx == 1
 */

static irqreturn_t
_boomerang_interrupt(int irq, struct net_device *dev)
{}

static irqreturn_t
vortex_boomerang_interrupt(int irq, void *dev_id)
{}

static int vortex_rx(struct net_device *dev)
{}

static int
boomerang_rx(struct net_device *dev)
{}

static void
vortex_down(struct net_device *dev, int final_down)
{}

static int
vortex_close(struct net_device *dev)
{}

static void
dump_tx_ring(struct net_device *dev)
{}

static struct net_device_stats *vortex_get_stats(struct net_device *dev)
{}

/*  Update statistics.
	Unlike with the EL3 we need not worry about interrupts changing
	the window setting from underneath us, but we must still guard
	against a race condition with a StatsUpdate interrupt updating the
	table.  This is done by checking that the ASM (!) code generated uses
	atomic updates with '+='.
	*/
static void update_stats(void __iomem *ioaddr, struct net_device *dev)
{}

static int vortex_nway_reset(struct net_device *dev)
{}

static int vortex_get_link_ksettings(struct net_device *dev,
				     struct ethtool_link_ksettings *cmd)
{}

static int vortex_set_link_ksettings(struct net_device *dev,
				     const struct ethtool_link_ksettings *cmd)
{}

static u32 vortex_get_msglevel(struct net_device *dev)
{}

static void vortex_set_msglevel(struct net_device *dev, u32 dbg)
{}

static int vortex_get_sset_count(struct net_device *dev, int sset)
{}

static void vortex_get_ethtool_stats(struct net_device *dev,
	struct ethtool_stats *stats, u64 *data)
{}


static void vortex_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{}

static void vortex_get_drvinfo(struct net_device *dev,
					struct ethtool_drvinfo *info)
{}

static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{}

static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{}

static const struct ethtool_ops vortex_ethtool_ops =;

#ifdef CONFIG_PCI
/*
 *	Must power the device up to do MDIO operations
 */
static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{}
#endif


/* Pre-Cyclone chips have no documented multicast filter, so the only
   multicast setting is to receive all multicast frames.  At least
   the chip has a very clean way to set the mode, unlike many others. */
static void set_rx_mode(struct net_device *dev)
{}

#if IS_ENABLED(CONFIG_VLAN_8021Q)
/* Setup the card so that it can receive frames with an 802.1q VLAN tag.
   Note that this must be done after each RxReset due to some backwards
   compatibility logic in the Cyclone and Tornado ASICs */

/* The Ethernet Type used for 802.1q tagged frames */
#define VLAN_ETHER_TYPE

static void set_8021q_mode(struct net_device *dev, int enable)
{}
#else

static void set_8021q_mode(struct net_device *dev, int enable)
{
}


#endif

/* MII transceiver control section.
   Read and write the MII registers using software-generated serial
   MDIO protocol.  See the MII specifications or DP83840A data sheet
   for details. */

/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
   "overclocking" issues. */
static void mdio_delay(struct vortex_private *vp)
{}

#define MDIO_SHIFT_CLK
#define MDIO_DIR_WRITE
#define MDIO_DATA_WRITE0
#define MDIO_DATA_WRITE1
#define MDIO_DATA_READ
#define MDIO_ENB_IN

/* Generate the preamble required for initial synchronization and
   a few older transceivers. */
static void mdio_sync(struct vortex_private *vp, int bits)
{}

static int mdio_read(struct net_device *dev, int phy_id, int location)
{}

static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
{}

/* ACPI: Advanced Configuration and Power Interface. */
/* Set Wake-On-LAN mode and put the board into D3 (power-down) state. */
static void acpi_set_WOL(struct net_device *dev)
{}


static void vortex_remove_one(struct pci_dev *pdev)
{}


static struct pci_driver vortex_driver =;


static int vortex_have_pci;
static int vortex_have_eisa;


static int __init vortex_init(void)
{}


static void __exit vortex_eisa_cleanup(void)
{}


static void __exit vortex_cleanup(void)
{}


module_init();
module_exit(vortex_cleanup);