linux/drivers/net/ethernet/amd/pcnet32.c

/* pcnet32.c: An AMD PCnet32 ethernet driver for linux. */
/*
 *	Copyright 1996-1999 Thomas Bogendoerfer
 *
 *	Derived from the lance driver written 1993,1994,1995 by Donald Becker.
 *
 *	Copyright 1993 United States Government as represented by the
 *	Director, National Security Agency.
 *
 *	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 PCnet32 and PCnetPCI based ethercards
 */
/**************************************************************************
 *  23 Oct, 2000.
 *  Fixed a few bugs, related to running the controller in 32bit mode.
 *
 *  Carsten Langgaard, [email protected]
 *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
 *
 *************************************************************************/

#define pr_fmt(fmt)

#define DRV_NAME
#define DRV_RELDATE
#define PFX

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/crc32.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/uaccess.h>

#include <asm/dma.h>
#include <asm/irq.h>

/*
 * PCI device identifiers for "new style" Linux PCI Device Drivers
 */
static const struct pci_device_id pcnet32_pci_tbl[] =;

MODULE_DEVICE_TABLE(pci, pcnet32_pci_tbl);

static int cards_found;

/*
 * VLB I/O addresses
 */
static unsigned int pcnet32_portlist[] =;

static int pcnet32_debug;
static int tx_start =;	/* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */
static int pcnet32vlb;		/* check for VLB cards ? */

static struct net_device *pcnet32_dev;

static int max_interrupt_work =;
static int rx_copybreak =;

#define PCNET32_PORT_AUI
#define PCNET32_PORT_10BT
#define PCNET32_PORT_GPSI
#define PCNET32_PORT_MII

#define PCNET32_PORT_PORTSEL
#define PCNET32_PORT_ASEL
#define PCNET32_PORT_100
#define PCNET32_PORT_FD

#define PCNET32_DMA_MASK

#define PCNET32_WATCHDOG_TIMEOUT
#define PCNET32_BLINK_TIMEOUT

/*
 * table to translate option values from tulip
 * to internal options
 */
static const unsigned char options_mapping[] =;

static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] =;

#define PCNET32_TEST_LEN

#define PCNET32_NUM_REGS

#define MAX_UNITS
static int options[MAX_UNITS];
static int full_duplex[MAX_UNITS];
static int homepna[MAX_UNITS];

/*
 *				Theory of Operation
 *
 * This driver uses the same software structure as the normal lance
 * driver. So look for a verbose description in lance.c. The differences
 * to the normal lance driver is the use of the 32bit mode of PCnet32
 * and PCnetPCI chips. Because these chips are 32bit chips, there is no
 * 16MB limitation and we don't need bounce buffers.
 */

/*
 * Set the number of Tx and Rx buffers, using Log_2(# buffers).
 * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
 * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
 */
#ifndef PCNET32_LOG_TX_BUFFERS
#define PCNET32_LOG_TX_BUFFERS
#define PCNET32_LOG_RX_BUFFERS
#define PCNET32_LOG_MAX_TX_BUFFERS
#define PCNET32_LOG_MAX_RX_BUFFERS
#endif

#define TX_RING_SIZE
#define TX_MAX_RING_SIZE

#define RX_RING_SIZE
#define RX_MAX_RING_SIZE

#define PKT_BUF_SKB
/* actual buffer length after being aligned */
#define PKT_BUF_SIZE
/* chip wants twos complement of the (aligned) buffer length */
#define NEG_BUF_SIZE

/* Offsets from base I/O address. */
#define PCNET32_WIO_RDP
#define PCNET32_WIO_RAP
#define PCNET32_WIO_RESET
#define PCNET32_WIO_BDP

#define PCNET32_DWIO_RDP
#define PCNET32_DWIO_RAP
#define PCNET32_DWIO_RESET
#define PCNET32_DWIO_BDP

#define PCNET32_TOTAL_SIZE

#define CSR0
#define CSR0_INIT
#define CSR0_START
#define CSR0_STOP
#define CSR0_TXPOLL
#define CSR0_INTEN
#define CSR0_IDON
#define CSR0_NORMAL
#define PCNET32_INIT_LOW
#define PCNET32_INIT_HIGH
#define CSR3
#define CSR4
#define CSR5
#define CSR5_SUSPEND
#define CSR15
#define PCNET32_MC_FILTER

#define PCNET32_79C970A

/* The PCNET32 Rx and Tx ring descriptors. */
struct pcnet32_rx_head {};

struct pcnet32_tx_head {};

/* The PCNET32 32-Bit initialization block, described in databook. */
struct pcnet32_init_block {};

/* PCnet32 access functions */
struct pcnet32_access {};

/*
 * The first field of pcnet32_private is read by the ethernet device
 * so the structure should be allocated using dma_alloc_coherent().
 */
struct pcnet32_private {};

static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
static int pcnet32_probe1(unsigned long, int, struct pci_dev *);
static int pcnet32_open(struct net_device *);
static int pcnet32_init_ring(struct net_device *);
static netdev_tx_t pcnet32_start_xmit(struct sk_buff *,
				      struct net_device *);
static void pcnet32_tx_timeout(struct net_device *dev, unsigned int txqueue);
static irqreturn_t pcnet32_interrupt(int, void *);
static int pcnet32_close(struct net_device *);
static struct net_device_stats *pcnet32_get_stats(struct net_device *);
static void pcnet32_load_multicast(struct net_device *dev);
static void pcnet32_set_multicast_list(struct net_device *);
static int pcnet32_ioctl(struct net_device *, struct ifreq *, int);
static void pcnet32_watchdog(struct timer_list *);
static int mdio_read(struct net_device *dev, int phy_id, int reg_num);
static void mdio_write(struct net_device *dev, int phy_id, int reg_num,
		       int val);
static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits);
static void pcnet32_ethtool_test(struct net_device *dev,
				 struct ethtool_test *eth_test, u64 * data);
static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1);
static int pcnet32_get_regs_len(struct net_device *dev);
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
			     void *ptr);
static void pcnet32_purge_tx_ring(struct net_device *dev);
static int pcnet32_alloc_ring(struct net_device *dev, const char *name);
static void pcnet32_free_ring(struct net_device *dev);
static void pcnet32_check_media(struct net_device *dev, int verbose);

static u16 pcnet32_wio_read_csr(unsigned long addr, int index)
{}

static void pcnet32_wio_write_csr(unsigned long addr, int index, u16 val)
{}

static u16 pcnet32_wio_read_bcr(unsigned long addr, int index)
{}

static void pcnet32_wio_write_bcr(unsigned long addr, int index, u16 val)
{}

static u16 pcnet32_wio_read_rap(unsigned long addr)
{}

static void pcnet32_wio_write_rap(unsigned long addr, u16 val)
{}

static void pcnet32_wio_reset(unsigned long addr)
{}

static int pcnet32_wio_check(unsigned long addr)
{}

static const struct pcnet32_access pcnet32_wio =;

static u16 pcnet32_dwio_read_csr(unsigned long addr, int index)
{}

static void pcnet32_dwio_write_csr(unsigned long addr, int index, u16 val)
{}

static u16 pcnet32_dwio_read_bcr(unsigned long addr, int index)
{}

static void pcnet32_dwio_write_bcr(unsigned long addr, int index, u16 val)
{}

static u16 pcnet32_dwio_read_rap(unsigned long addr)
{}

static void pcnet32_dwio_write_rap(unsigned long addr, u16 val)
{}

static void pcnet32_dwio_reset(unsigned long addr)
{}

static int pcnet32_dwio_check(unsigned long addr)
{}

static const struct pcnet32_access pcnet32_dwio =;

static void pcnet32_netif_stop(struct net_device *dev)
{}

static void pcnet32_netif_start(struct net_device *dev)
{}

/*
 * Allocate space for the new sized tx ring.
 * Free old resources
 * Save new resources.
 * Any failure keeps old resources.
 * Must be called with lp->lock held.
 */
static void pcnet32_realloc_tx_ring(struct net_device *dev,
				    struct pcnet32_private *lp,
				    unsigned int size)
{}

/*
 * Allocate space for the new sized rx ring.
 * Re-use old receive buffers.
 *   alloc extra buffers
 *   free unneeded buffers
 *   free unneeded buffers
 * Save new resources.
 * Any failure keeps old resources.
 * Must be called with lp->lock held.
 */
static void pcnet32_realloc_rx_ring(struct net_device *dev,
				    struct pcnet32_private *lp,
				    unsigned int size)
{}

static void pcnet32_purge_rx_ring(struct net_device *dev)
{}

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

/*
 * lp->lock must be held.
 */
static int pcnet32_suspend(struct net_device *dev, unsigned long *flags,
			   int can_sleep)
{}

static void pcnet32_clr_suspend(struct pcnet32_private *lp, ulong ioaddr)
{}

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

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

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

static u32 pcnet32_get_link(struct net_device *dev)
{}

static u32 pcnet32_get_msglevel(struct net_device *dev)
{}

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

static int pcnet32_nway_reset(struct net_device *dev)
{}

static void pcnet32_get_ringparam(struct net_device *dev,
				  struct ethtool_ringparam *ering,
				  struct kernel_ethtool_ringparam *kernel_ering,
				  struct netlink_ext_ack *extack)
{}

static int pcnet32_set_ringparam(struct net_device *dev,
				 struct ethtool_ringparam *ering,
				 struct kernel_ethtool_ringparam *kernel_ering,
				 struct netlink_ext_ack *extack)
{}

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

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

static void pcnet32_ethtool_test(struct net_device *dev,
				 struct ethtool_test *test, u64 * data)
{}				/* end pcnet32_ethtool_test */

static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
{}				/* end pcnet32_loopback_test  */

static int pcnet32_set_phys_id(struct net_device *dev,
			       enum ethtool_phys_id_state state)
{}

/*
 * process one receive descriptor entry
 */

static void pcnet32_rx_entry(struct net_device *dev,
			     struct pcnet32_private *lp,
			     struct pcnet32_rx_head *rxp,
			     int entry)
{}

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

static int pcnet32_tx(struct net_device *dev)
{}

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

#define PCNET32_REGS_PER_PHY
#define PCNET32_MAX_PHYS
static int pcnet32_get_regs_len(struct net_device *dev)
{}

static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
			     void *ptr)
{}

static const struct ethtool_ops pcnet32_ethtool_ops =;

/* only probes for non-PCI devices, the rest are handled by
 * pci_register_driver via pcnet32_probe_pci */

static void pcnet32_probe_vlbus(unsigned int *pcnet32_portlist)
{}

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

static const struct net_device_ops pcnet32_netdev_ops =;

/* pcnet32_probe1
 *  Called from both pcnet32_probe_vlbus and pcnet_probe_pci.
 *  pdev will be NULL when called from pcnet32_probe_vlbus.
 */
static int
pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
{}

/* if any allocation fails, caller must also call pcnet32_free_ring */
static int pcnet32_alloc_ring(struct net_device *dev, const char *name)
{}

static void pcnet32_free_ring(struct net_device *dev)
{}

static int pcnet32_open(struct net_device *dev)
{}

/*
 * The LANCE has been halted for one reason or another (busmaster memory
 * arbitration error, Tx FIFO underflow, driver stopped it to reconfigure,
 * etc.).  Modern LANCE variants always reload their ring-buffer
 * configuration when restarted, so we must reinitialize our ring
 * context before restarting.  As part of this reinitialization,
 * find all packets still on the Tx ring and pretend that they had been
 * sent (in effect, drop the packets on the floor) - the higher-level
 * protocols will time out and retransmit.  It'd be better to shuffle
 * these skbs to a temp list and then actually re-Tx them after
 * restarting the chip, but I'm too lazy to do so right now.  [email protected]
 */

static void pcnet32_purge_tx_ring(struct net_device *dev)
{}

/* Initialize the PCNET32 Rx and Tx rings. */
static int pcnet32_init_ring(struct net_device *dev)
{}

/* the pcnet32 has been issued a stop or reset.  Wait for the stop bit
 * then flush the pending transmit operations, re-initialize the ring,
 * and tell the chip to initialize.
 */
static void pcnet32_restart(struct net_device *dev, unsigned int csr0_bits)
{}

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

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

/* The PCNET32 interrupt handler. */
static irqreturn_t
pcnet32_interrupt(int irq, void *dev_id)
{}

static int pcnet32_close(struct net_device *dev)
{}

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

/* taken from the sunlance driver, which it took from the depca driver */
static void pcnet32_load_multicast(struct net_device *dev)
{}

/*
 * Set or clear the multicast filter for this adaptor.
 */
static void pcnet32_set_multicast_list(struct net_device *dev)
{}

/* This routine assumes that the lp->lock is held */
static int mdio_read(struct net_device *dev, int phy_id, int reg_num)
{}

/* This routine assumes that the lp->lock is held */
static void mdio_write(struct net_device *dev, int phy_id, int reg_num, int val)
{}

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

static int pcnet32_check_otherphy(struct net_device *dev)
{}

/*
 * Show the status of the media.  Similar to mii_check_media however it
 * correctly shows the link speed for all (tested) pcnet32 variants.
 * Devices with no mii just report link state without speed.
 *
 * Caller is assumed to hold and release the lp->lock.
 */

static void pcnet32_check_media(struct net_device *dev, int verbose)
{}

/*
 * Check for loss of link and link establishment.
 * Could possibly be changed to use mii_check_media instead.
 */

static void pcnet32_watchdog(struct timer_list *t)
{}

static int __maybe_unused pcnet32_pm_suspend(struct device *device_d)
{}

static int __maybe_unused pcnet32_pm_resume(struct device *device_d)
{}

static void pcnet32_remove_one(struct pci_dev *pdev)
{}

static SIMPLE_DEV_PM_OPS(pcnet32_pm_ops, pcnet32_pm_suspend, pcnet32_pm_resume);

static struct pci_driver pcnet32_driver =;

/* An additional parameter that may be passed in... */
static int debug =;
static int tx_start_pt =;
static int pcnet32_have_pci;

module_param(debug, int, 0);
MODULE_PARM_DESC();
module_param(max_interrupt_work, int, 0);
MODULE_PARM_DESC();
module_param(rx_copybreak, int, 0);
MODULE_PARM_DESC();
module_param(tx_start_pt, int, 0);
MODULE_PARM_DESC();
module_param(pcnet32vlb, int, 0);
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();
/* Module Parameter for HomePNA cards added by Patrick Simmons, 2004 */
module_param_array();
MODULE_PARM_DESC();

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

#define PCNET32_MSG_DEFAULT

static int __init pcnet32_init_module(void)
{}

static void __exit pcnet32_cleanup_module(void)
{}

module_init();
module_exit(pcnet32_cleanup_module);