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

/* typhoon.c: A Linux Ethernet device driver for 3Com 3CR990 family of NICs */
/*
	Written 2002-2004 by David Dillow <[email protected]>
	Based on code written 1998-2000 by Donald Becker <[email protected]> and
	Linux 2.2.x driver by David P. McLean <[email protected]>.

	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 software is available on a public web site. It may enable
	cryptographic capabilities of the 3Com hardware, and may be
	exported from the United States under License Exception "TSU"
	pursuant to 15 C.F.R. Section 740.13(e).

	This work was funded by the National Library of Medicine under
	the Department of Energy project number 0274DD06D1 and NLM project
	number Y1-LM-2015-01.

	This driver is designed for the 3Com 3CR990 Family of cards with the
	3XP Processor. It has been tested on x86 and sparc64.

	KNOWN ISSUES:
	*) Cannot DMA Rx packets to a 2 byte aligned address. Also firmware
		issue. Hopefully 3Com will fix it.
	*) Waiting for a command response takes 8ms due to non-preemptable
		polling. Only significant for getting stats and creating
		SAs, but an ugly wart never the less.

	TODO:
	*) Doesn't do IPSEC offloading. Yet. Keep yer pants on, it's coming.
	*) Add more support for ethtool (especially for NIC stats)
	*) Allow disabling of RX checksum offloading
	*) Fix MAC changing to work while the interface is up
		(Need to put commands on the TX ring, which changes
		the locking)
	*) Add in FCS to {rx,tx}_bytes, since the hardware doesn't. See
		http://oss.sgi.com/cgi-bin/mesg.cgi?a=netdev&i=20031215152211.7003fe8e.rddunlap%40osdl.org
*/

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

/* Should we use MMIO or Port IO?
 * 0: Port IO
 * 1: MMIO
 * 2: Try MMIO, fallback to Port IO
 */
static unsigned int use_mmio =;

/* end user-configurable values */

/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
 */
static const int multicast_filter_limit =;

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

/* Keep the ring sizes a power of two for compile 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.
 *
 * We don't currently use the Hi Tx ring so, don't make it very big.
 *
 * Beware that if we start using the Hi Tx ring, we will need to change
 * typhoon_num_free_tx() and typhoon_tx_complete() to account for that.
 */
#define TXHI_ENTRIES
#define TXLO_ENTRIES
#define RX_ENTRIES
#define COMMAND_ENTRIES
#define RESPONSE_ENTRIES

#define COMMAND_RING_SIZE
#define RESPONSE_RING_SIZE

/* The 3XP will preload and remove 64 entries from the free buffer
 * list, and we need one entry to keep the ring from wrapping, so
 * to keep this a power of two, we use 128 entries.
 */
#define RXFREE_ENTRIES
#define RXENT_ENTRIES

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

/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT

#define PKT_BUF_SZ
#define FIRMWARE_NAME

#define pr_fmt(fmt)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.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/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/bitops.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#include <linux/in6.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>

#include "typhoon.h"

MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_FIRMWARE();
MODULE_DESCRIPTION();
MODULE_PARM_DESC();
MODULE_PARM_DESC();
module_param(rx_copybreak, int, 0);
module_param(use_mmio, int, 0);

#if TXLO_ENTRIES <= (2 * MAX_SKB_FRAGS)
#error TX ring too small!
#endif

struct typhoon_card_info {};

#define TYPHOON_CRYPTO_NONE
#define TYPHOON_CRYPTO_DES
#define TYPHOON_CRYPTO_3DES
#define TYPHOON_CRYPTO_VARIABLE
#define TYPHOON_FIBER
#define TYPHOON_WAKEUP_NEEDS_RESET

enum typhoon_cards {};

/* directly indexed by enum typhoon_cards, above */
static struct typhoon_card_info typhoon_card_info[] =;

/* Notes on the new subsystem numbering scheme:
 * bits 0-1 indicate crypto capabilities: (0) variable, (1) DES, or (2) 3DES
 * bit 4 indicates if this card has secured firmware (we don't support it)
 * bit 8 indicates if this is a (0) copper or (1) fiber card
 * bits 12-16 indicate card type: (0) client and (1) server
 */
static const struct pci_device_id typhoon_pci_tbl[] =;
MODULE_DEVICE_TABLE(pci, typhoon_pci_tbl);

/* Define the shared memory area
 * Align everything the 3XP will normally be using.
 * We'll need to move/align txHi if we start using that ring.
 */
#define __3xp_aligned
struct typhoon_shared {} __packed;

struct rxbuff_ent {};

struct typhoon {};

enum completion_wait_values {};

/* These are the values for the typhoon.card_state variable.
 * These determine where the statistics will come from in get_stats().
 * The sleep image does not support the statistics we need.
 */
enum state_values {};

/* PCI writes are not guaranteed to be posted in order, but outstanding writes
 * cannot pass a read, so this forces current writes to post.
 */
#define typhoon_post_pci_writes(x)

/* We'll wait up to six seconds for a reset, and half a second normally.
 */
#define TYPHOON_UDELAY
#define TYPHOON_RESET_TIMEOUT_SLEEP
#define TYPHOON_RESET_TIMEOUT_NOSLEEP
#define TYPHOON_WAIT_TIMEOUT

#if defined(NETIF_F_TSO)
#define skb_tso_size(x)
#define TSO_NUM_DESCRIPTORS
#define TSO_OFFLOAD_ON
#else
#define NETIF_F_TSO
#define skb_tso_size
#define TSO_NUM_DESCRIPTORS
#define TSO_OFFLOAD_ON
#endif

static inline void
typhoon_inc_index(u32 *index, const int count, const int num_entries)
{}

static inline void
typhoon_inc_cmd_index(u32 *index, const int count)
{}

static inline void
typhoon_inc_resp_index(u32 *index, const int count)
{}

static inline void
typhoon_inc_rxfree_index(u32 *index, const int count)
{}

static inline void
typhoon_inc_tx_index(u32 *index, const int count)
{}

static inline void
typhoon_inc_rx_index(u32 *index, const int count)
{}

static int
typhoon_reset(void __iomem *ioaddr, int wait_type)
{}

static int
typhoon_wait_status(void __iomem *ioaddr, u32 wait_value)
{}

static inline void
typhoon_media_status(struct net_device *dev, struct resp_desc *resp)
{}

static inline void
typhoon_hello(struct typhoon *tp)
{}

static int
typhoon_process_response(struct typhoon *tp, int resp_size,
				struct resp_desc *resp_save)
{}

static inline int
typhoon_num_free(int lastWrite, int lastRead, int ringSize)
{}

static inline int
typhoon_num_free_cmd(struct typhoon *tp)
{}

static inline int
typhoon_num_free_resp(struct typhoon *tp)
{}

static inline int
typhoon_num_free_tx(struct transmit_ring *ring)
{}

static int
typhoon_issue_command(struct typhoon *tp, int num_cmd, struct cmd_desc *cmd,
		      int num_resp, struct resp_desc *resp)
{}

static inline void
typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
			u32 ring_dma)
{}

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

static void
typhoon_set_rx_mode(struct net_device *dev)
{}

static int
typhoon_do_get_stats(struct typhoon *tp)
{}

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

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

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

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

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

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

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

static const struct ethtool_ops typhoon_ethtool_ops =;

static int
typhoon_wait_interrupt(void __iomem *ioaddr)
{}

#define shared_offset(x)

static void
typhoon_init_interface(struct typhoon *tp)
{}

static void
typhoon_init_rings(struct typhoon *tp)
{}

static const struct firmware *typhoon_fw;

static int
typhoon_request_firmware(struct typhoon *tp)
{}

static int
typhoon_download_firmware(struct typhoon *tp)
{}

static int
typhoon_boot_3XP(struct typhoon *tp, u32 initial_status)
{}

static u32
typhoon_clean_tx(struct typhoon *tp, struct transmit_ring *txRing,
			volatile __le32 * index)
{}

static void
typhoon_tx_complete(struct typhoon *tp, struct transmit_ring *txRing,
			volatile __le32 * index)
{}

static void
typhoon_recycle_rx_skb(struct typhoon *tp, u32 idx)
{}

static int
typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx)
{}

static int
typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * ready,
	   volatile __le32 * cleared, int budget)
{}

static void
typhoon_fill_free_ring(struct typhoon *tp)
{}

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

static irqreturn_t
typhoon_interrupt(int irq, void *dev_instance)
{}

static void
typhoon_free_rx_rings(struct typhoon *tp)
{}

static int
typhoon_sleep_early(struct typhoon *tp, __le16 events)
{}

static int
typhoon_sleep(struct typhoon *tp, pci_power_t state, __le16 events)
{}

static int
typhoon_wakeup(struct typhoon *tp, int wait_type)
{}

static int
typhoon_start_runtime(struct typhoon *tp)
{}

static int
typhoon_stop_runtime(struct typhoon *tp, int wait_type)
{}

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

static int
typhoon_open(struct net_device *dev)
{}

static int
typhoon_close(struct net_device *dev)
{}

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

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

static int
typhoon_test_mmio(struct pci_dev *pdev)
{}

#if MAX_SKB_FRAGS > 32

#include <net/vxlan.h>

static netdev_features_t typhoon_features_check(struct sk_buff *skb,
						struct net_device *dev,
						netdev_features_t features)
{
	if (skb_shinfo(skb)->nr_frags > 32 && skb_is_gso(skb))
		features &= ~NETIF_F_GSO_MASK;

	features = vlan_features_check(skb, features);
	return vxlan_features_check(skb, features);
}
#endif

static const struct net_device_ops typhoon_netdev_ops =;

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

static void
typhoon_remove_one(struct pci_dev *pdev)
{}

static SIMPLE_DEV_PM_OPS(typhoon_pm_ops, typhoon_suspend, typhoon_resume);

static struct pci_driver typhoon_driver =;

static int __init
typhoon_init(void)
{}

static void __exit
typhoon_cleanup(void)
{}

module_init();
module_exit(typhoon_cleanup);