linux/drivers/net/ethernet/smsc/epic100.c

/* epic100.c: A SMC 83c170 EPIC/100 Fast Ethernet driver for Linux. */
/*
	Written/copyright 1997-2001 by Donald Becker.

	This software may be used and distributed according to the terms of
	the GNU General Public License (GPL), incorporated herein by reference.
	Drivers based on or derived from this code fall under the GPL and must
	retain the authorship, copyright and license notice.  This file is not
	a complete program and may only be used when the entire operating
	system is licensed under the GPL.

	This driver is for the SMC83c170/175 "EPIC" series, as used on the
	SMC EtherPower II 9432 PCI adapter, and several CardBus cards.

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

	Information and updates available at
	http://www.scyld.com/network/epic100.html
	[this link no longer provides anything useful -jgarzik]

	---------------------------------------------------------------------

*/

#define DRV_NAME
#define DRV_VERSION
#define DRV_RELDATE

/* The user-configurable values.
   These may be modified when a driver module is loaded.*/

static int debug =;			/* 1 normal messages, 0 quiet .. 7 verbose. */

/* Used to pass the full-duplex flag, etc. */
#define MAX_UNITS
static int options[MAX_UNITS] =;
static int full_duplex[MAX_UNITS] =;

/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
   Setting to > 1518 effectively disables this feature. */
static int rx_copybreak;

/* Operational parameters that are set at compile time. */

/* Keep the ring sizes a power of two for operational efficiency.
   The compiler will convert <unsigned>'%'<2^N> into a bit mask.
   Making the Tx ring too large decreases the effectiveness of channel
   bonding and packet priority.
   There are no ill effects from too-large receive rings. */
#define TX_RING_SIZE
#define TX_QUEUE_LEN
#define RX_RING_SIZE
#define TX_TOTAL_SIZE
#define RX_TOTAL_SIZE

/* Operational parameters that usually are not changed. */
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT

#define PKT_BUF_SZ

/* Bytes transferred to chip before transmission starts. */
/* Initial threshold, increased on underflow, rounded down to 4 byte units. */
#define TX_FIFO_THRESH
#define RX_FIFO_THRESH

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/crc32.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#include <asm/byteorder.h>

/* These identify the driver base version and may not be removed. */
static char version[] =;
static char version2[] =;

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

module_param(debug, int, 0);
module_param(rx_copybreak, int, 0);
module_param_array();
module_param_array();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
MODULE_PARM_DESC();

/*
				Theory of Operation

I. Board Compatibility

This device driver is designed for the SMC "EPIC/100", the SMC
single-chip Ethernet controllers for PCI.  This chip is used on
the SMC EtherPower II boards.

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 will assign the
PCI INTA signal to a (preferably otherwise unused) system IRQ line.
Note: Kernel versions earlier than 1.3.73 do not support shared PCI
interrupt lines.

III. Driver operation

IIIa. Ring buffers

IVb. References

http://www.smsc.com/media/Downloads_Public/discontinued/83c171.pdf
http://www.smsc.com/media/Downloads_Public/discontinued/83c175.pdf
http://scyld.com/expert/NWay.html
http://www.national.com/pf/DP/DP83840A.html

IVc. Errata

*/


enum chip_capability_flags {};

#define EPIC_TOTAL_SIZE
#define USE_IO_OPS

#ifdef USE_IO_OPS
#define EPIC_BAR
#else
#define EPIC_BAR
#endif

chip_t;


struct epic_chip_info {};


/* indexed by chip_t */
static const struct epic_chip_info pci_id_tbl[] =;


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

#define ew16(reg, val)
#define ew32(reg, val)
#define er8(reg)
#define er16(reg)
#define er32(reg)

/* Offsets to registers, using the (ugh) SMC names. */
enum epic_registers {};

/* Interrupt register bits, using my own meaningful names. */
enum IntrStatus {};
enum CommandBits {};

#define EpicRemoved

#define EpicNapiEvent
#define EpicNormalEvent

static const u16 media2miictl[16] =;

/*
 * The EPIC100 Rx and Tx buffer descriptors.  Note that these
 * really ARE host-endian; it's not a misannotation.  We tell
 * the card to byteswap them internally on big-endian hosts -
 * look for #ifdef __BIG_ENDIAN in epic_open().
 */

struct epic_tx_desc {};

struct epic_rx_desc {};

enum desc_status_bits {};

#define PRIV_ALIGN
struct epic_private {};

static int epic_open(struct net_device *dev);
static int read_eeprom(struct epic_private *, int);
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 loc, int val);
static void epic_restart(struct net_device *dev);
static void epic_timer(struct timer_list *t);
static void epic_tx_timeout(struct net_device *dev, unsigned int txqueue);
static void epic_init_ring(struct net_device *dev);
static netdev_tx_t epic_start_xmit(struct sk_buff *skb,
				   struct net_device *dev);
static int epic_rx(struct net_device *dev, int budget);
static int epic_poll(struct napi_struct *napi, int budget);
static irqreturn_t epic_interrupt(int irq, void *dev_instance);
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static const struct ethtool_ops netdev_ethtool_ops;
static int epic_close(struct net_device *dev);
static struct net_device_stats *epic_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);

static const struct net_device_ops epic_netdev_ops =;

static int epic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{}

/* Serial EEPROM section. */

/*  EEPROM_Ctrl bits. */
#define EE_SHIFT_CLK
#define EE_CS
#define EE_DATA_WRITE
#define EE_WRITE_0
#define EE_WRITE_1
#define EE_DATA_READ
#define EE_ENB

/* Delay between EEPROM clock transitions.
   This serves to flush the operation to the PCI bus.
 */

#define eeprom_delay()

/* The EEPROM commands include the alway-set leading bit. */
#define EE_WRITE_CMD
#define EE_READ64_CMD
#define EE_READ256_CMD
#define EE_ERASE_CMD

static void epic_disable_int(struct net_device *dev, struct epic_private *ep)
{}

static inline void __epic_pci_commit(void __iomem *ioaddr)
{}

static inline void epic_napi_irq_off(struct net_device *dev,
				     struct epic_private *ep)
{}

static inline void epic_napi_irq_on(struct net_device *dev,
				    struct epic_private *ep)
{}

static int read_eeprom(struct epic_private *ep, int location)
{}

#define MII_READOP
#define MII_WRITEOP
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 loc, int value)
{}


static int epic_open(struct net_device *dev)
{}

/* Reset the chip to recover from a PCI transaction error.
   This may occur at interrupt time. */
static void epic_pause(struct net_device *dev)
{}

static void epic_restart(struct net_device *dev)
{}

static void check_media(struct net_device *dev)
{}

static void epic_timer(struct timer_list *t)
{}

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

/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
static void epic_init_ring(struct net_device *dev)
{}

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

static void epic_tx_error(struct net_device *dev, struct epic_private *ep,
			  int status)
{}

static void epic_tx(struct net_device *dev, struct epic_private *ep)
{}

/* The interrupt handler does all of the Rx thread work and cleans up
   after the Tx thread. */
static irqreturn_t epic_interrupt(int irq, void *dev_instance)
{}

static int epic_rx(struct net_device *dev, int budget)
{}

static void epic_rx_err(struct net_device *dev, struct epic_private *ep)
{}

static int epic_poll(struct napi_struct *napi, int budget)
{}

static int epic_close(struct net_device *dev)
{}

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

/* Set or clear the multicast filter for this adaptor.
   Note that we only use exclusion around actually queueing the
   new frame, not around filling ep->setup_frame.  This is non-deterministic
   when re-entered but still correct. */

static void set_rx_mode(struct net_device *dev)
{}

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

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

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

static int netdev_nway_reset(struct net_device *dev)
{}

static u32 netdev_get_link(struct net_device *dev)
{}

static u32 netdev_get_msglevel(struct net_device *dev)
{}

static void netdev_set_msglevel(struct net_device *dev, u32 value)
{}

static int ethtool_begin(struct net_device *dev)
{}

static void ethtool_complete(struct net_device *dev)
{}

static const struct ethtool_ops netdev_ethtool_ops =;

static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{}


static void epic_remove_one(struct pci_dev *pdev)
{}

static int __maybe_unused epic_suspend(struct device *dev_d)
{}


static int __maybe_unused epic_resume(struct device *dev_d)
{}

static SIMPLE_DEV_PM_OPS(epic_pm_ops, epic_suspend, epic_resume);

static struct pci_driver epic_driver =;


static int __init epic_init (void)
{}


static void __exit epic_cleanup (void)
{}


module_init();
module_exit(epic_cleanup);