linux/drivers/net/ethernet/myricom/myri10ge/myri10ge.c

/*************************************************************************
 * myri10ge.c: Myricom Myri-10G Ethernet driver.
 *
 * Copyright (C) 2005 - 2011 Myricom, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Myricom, Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * If the eeprom on your board is not recent enough, you will need to get a
 * newer firmware image at:
 *   http://www.myri.com/scs/download-Myri10GE.html
 *
 * Contact Information:
 *   <[email protected]>
 *   Myricom, Inc., 325N Santa Anita Avenue, Arcadia, CA 91006
 *************************************************************************/

#define pr_fmt(fmt)

#include <linux/tcp.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/dca.h>
#include <linux/ip.h>
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/ethtool.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
#include <linux/crc32.h>
#include <linux/moduleparam.h>
#include <linux/io.h>
#include <linux/log2.h>
#include <linux/slab.h>
#include <linux/prefetch.h>
#include <net/checksum.h>
#include <net/gso.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <asm/byteorder.h>
#include <asm/processor.h>

#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"

#define MYRI10GE_VERSION_STR

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

#define MYRI10GE_MAX_ETHER_MTU

#define MYRI10GE_ETH_STOPPED
#define MYRI10GE_ETH_STOPPING
#define MYRI10GE_ETH_STARTING
#define MYRI10GE_ETH_RUNNING
#define MYRI10GE_ETH_OPEN_FAILED

#define MYRI10GE_EEPROM_STRINGS_SIZE
#define MYRI10GE_MAX_SEND_DESC_TSO

#define MYRI10GE_NO_CONFIRM_DATA
#define MYRI10GE_NO_RESPONSE_RESULT

#define MYRI10GE_ALLOC_ORDER
#define MYRI10GE_ALLOC_SIZE
#define MYRI10GE_MAX_FRAGS_PER_FRAME

#define MYRI10GE_MAX_SLICES

struct myri10ge_rx_buffer_state {};

struct myri10ge_tx_buffer_state {};

struct myri10ge_cmd {};

struct myri10ge_rx_buf {};

struct myri10ge_tx_buf {};

struct myri10ge_rx_done {};

struct myri10ge_slice_netstats {};

struct myri10ge_slice_state {};

struct myri10ge_priv {};

static char *myri10ge_fw_unaligned =;
static char *myri10ge_fw_aligned =;
static char *myri10ge_fw_rss_unaligned =;
static char *myri10ge_fw_rss_aligned =;
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();

/* Careful: must be accessed under kernel_param_lock() */
static char *myri10ge_fw_name =;
module_param(myri10ge_fw_name, charp, 0644);
MODULE_PARM_DESC();

#define MYRI10GE_MAX_BOARDS
static char *myri10ge_fw_names[MYRI10GE_MAX_BOARDS] =;
module_param_array_named();
MODULE_PARM_DESC();

static int myri10ge_ecrc_enable =;
module_param(myri10ge_ecrc_enable, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_small_bytes =;	/* -1 == auto */
module_param(myri10ge_small_bytes, int, 0644);
MODULE_PARM_DESC();

static int myri10ge_msi =;	/* enable msi by default */
module_param(myri10ge_msi, int, 0644);
MODULE_PARM_DESC();

static int myri10ge_intr_coal_delay =;
module_param(myri10ge_intr_coal_delay, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_flow_control =;
module_param(myri10ge_flow_control, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_deassert_wait =;
module_param(myri10ge_deassert_wait, int, 0644);
MODULE_PARM_DESC();

static int myri10ge_force_firmware =;
module_param(myri10ge_force_firmware, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_initial_mtu =;
module_param(myri10ge_initial_mtu, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_napi_weight =;
module_param(myri10ge_napi_weight, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_watchdog_timeout =;
module_param(myri10ge_watchdog_timeout, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_max_irq_loops =;
module_param(myri10ge_max_irq_loops, int, 0444);
MODULE_PARM_DESC();

#define MYRI10GE_MSG_DEFAULT

static int myri10ge_debug =;	/* defaults above */
module_param(myri10ge_debug, int, 0);
MODULE_PARM_DESC();

static int myri10ge_fill_thresh =;
module_param(myri10ge_fill_thresh, int, 0644);
MODULE_PARM_DESC();

static int myri10ge_reset_recover =;

static int myri10ge_max_slices =;
module_param(myri10ge_max_slices, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_rss_hash =;
module_param(myri10ge_rss_hash, int, 0444);
MODULE_PARM_DESC();

static int myri10ge_dca =;
module_param(myri10ge_dca, int, 0444);
MODULE_PARM_DESC();

#define MYRI10GE_FW_OFFSET
#define MYRI10GE_HIGHPART_TO_U32(X)
#define MYRI10GE_LOWPART_TO_U32(X)

#define myri10ge_pio_copy(to,from,size)

static void myri10ge_set_multicast_list(struct net_device *dev);
static netdev_tx_t myri10ge_sw_tso(struct sk_buff *skb,
					 struct net_device *dev);

static inline void put_be32(__be32 val, __be32 __iomem * p)
{}

static void myri10ge_get_stats(struct net_device *dev,
			       struct rtnl_link_stats64 *stats);

static void set_fw_name(struct myri10ge_priv *mgp, char *name, bool allocated)
{}

static int
myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
		  struct myri10ge_cmd *data, int atomic)
{}

/*
 * The eeprom strings on the lanaiX have the format
 * SN=x\0
 * MAC=x:x:x:x:x:x\0
 * PT:ddd mmm xx xx:xx:xx xx\0
 * PV:ddd mmm xx xx:xx:xx xx\0
 */
static int myri10ge_read_mac_addr(struct myri10ge_priv *mgp)
{}

/*
 * Enable or disable periodic RDMAs from the host to make certain
 * chipsets resend dropped PCIe messages
 */

static void myri10ge_dummy_rdma(struct myri10ge_priv *mgp, int enable)
{}

static int
myri10ge_validate_firmware(struct myri10ge_priv *mgp,
			   struct mcp_gen_header *hdr)
{}

static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size)
{}

static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp)
{}

static int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp)
{}

static int myri10ge_load_firmware(struct myri10ge_priv *mgp, int adopt)
{}

static int myri10ge_update_mac_address(struct myri10ge_priv *mgp,
				       const u8 * addr)
{}

static int myri10ge_change_pause(struct myri10ge_priv *mgp, int pause)
{}

static void
myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic)
{}

static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
{}

static int myri10ge_reset(struct myri10ge_priv *mgp)
{}

#ifdef CONFIG_MYRI10GE_DCA
static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on)
{}

static void
myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
{}

static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss)
{}

static void myri10ge_setup_dca(struct myri10ge_priv *mgp)
{}

static void myri10ge_teardown_dca(struct myri10ge_priv *mgp)
{}

static int myri10ge_notify_dca_device(struct device *dev, void *data)
{}
#endif				/* CONFIG_MYRI10GE_DCA */

static inline void
myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst,
		    struct mcp_kreq_ether_recv *src)
{}

static void
myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
			int bytes, int watchdog)
{}

static inline void
myri10ge_unmap_rx_page(struct pci_dev *pdev,
		       struct myri10ge_rx_buffer_state *info, int bytes)
{}

/*
 * GRO does not support acceleration of tagged vlan frames, and
 * this NIC does not support vlan tag offload, so we must pop
 * the tag ourselves to be able to achieve GRO performance that
 * is comparable to LRO.
 */

static inline void
myri10ge_vlan_rx(struct net_device *dev, void *addr, struct sk_buff *skb)
{}

#define MYRI10GE_HLEN

static inline int
myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum)
{}

static inline void
myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index)
{}

static inline int
myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
{}

static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
{}

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

static irqreturn_t myri10ge_intr(int irq, void *arg)
{}

static int
myri10ge_get_link_ksettings(struct net_device *netdev,
			    struct ethtool_link_ksettings *cmd)
{}

static void
myri10ge_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info)
{}

static int myri10ge_get_coalesce(struct net_device *netdev,
				 struct ethtool_coalesce *coal,
				 struct kernel_ethtool_coalesce *kernel_coal,
				 struct netlink_ext_ack *extack)
{}

static int myri10ge_set_coalesce(struct net_device *netdev,
				 struct ethtool_coalesce *coal,
				 struct kernel_ethtool_coalesce *kernel_coal,
				 struct netlink_ext_ack *extack)
{}

static void
myri10ge_get_pauseparam(struct net_device *netdev,
			struct ethtool_pauseparam *pause)
{}

static int
myri10ge_set_pauseparam(struct net_device *netdev,
			struct ethtool_pauseparam *pause)
{}

static void
myri10ge_get_ringparam(struct net_device *netdev,
		       struct ethtool_ringparam *ring,
		       struct kernel_ethtool_ringparam *kernel_ring,
		       struct netlink_ext_ack *extack)
{}

static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] =;

static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] =;

#define MYRI10GE_NET_STATS_LEN
#define MYRI10GE_MAIN_STATS_LEN
#define MYRI10GE_SLICE_STATS_LEN

static void
myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
{}

static int myri10ge_get_sset_count(struct net_device *netdev, int sset)
{}

static void
myri10ge_get_ethtool_stats(struct net_device *netdev,
			   struct ethtool_stats *stats, u64 * data)
{}

static void myri10ge_set_msglevel(struct net_device *netdev, u32 value)
{}

static u32 myri10ge_get_msglevel(struct net_device *netdev)
{}

/*
 * Use a low-level command to change the LED behavior. Rather than
 * blinking (which is the normal case), when identify is used, the
 * yellow LED turns solid.
 */
static int myri10ge_led(struct myri10ge_priv *mgp, int on)
{}

static int
myri10ge_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
{}

static const struct ethtool_ops myri10ge_ethtool_ops =;

static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
{}

static void myri10ge_free_rings(struct myri10ge_slice_state *ss)
{}

static int myri10ge_request_irq(struct myri10ge_priv *mgp)
{}

static void myri10ge_free_irq(struct myri10ge_priv *mgp)
{}

static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice)
{}

static int myri10ge_set_stats(struct myri10ge_priv *mgp, int slice)
{}

static int myri10ge_open(struct net_device *dev)
{}

static int myri10ge_close(struct net_device *dev)
{}

/* copy an array of struct mcp_kreq_ether_send's to the mcp.  Copy
 * backwards one at a time and handle ring wraps */

static inline void
myri10ge_submit_req_backwards(struct myri10ge_tx_buf *tx,
			      struct mcp_kreq_ether_send *src, int cnt)
{}

/*
 * copy an array of struct mcp_kreq_ether_send's to the mcp.  Copy
 * at most 32 bytes at a time, so as to avoid involving the software
 * pio handler in the nic.   We re-write the first segment's flags
 * to mark them valid only after writing the entire chain.
 */

static inline void
myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
		    int cnt)
{}

static void myri10ge_unmap_tx_dma(struct myri10ge_priv *mgp,
				  struct myri10ge_tx_buf *tx, int idx)
{}

/*
 * Transmit a packet.  We need to split the packet so that a single
 * segment does not cross myri10ge->tx_boundary, so this makes segment
 * counting tricky.  So rather than try to count segments up front, we
 * just give up if there are too few segments to hold a reasonably
 * fragmented packet currently available.  If we run
 * out of segments while preparing a packet for DMA, we just linearize
 * it and try again.
 */

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

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

static void myri10ge_get_stats(struct net_device *dev,
			       struct rtnl_link_stats64 *stats)
{}

static void myri10ge_set_multicast_list(struct net_device *dev)
{}

static int myri10ge_set_mac_address(struct net_device *dev, void *addr)
{}

static int myri10ge_change_mtu(struct net_device *dev, int new_mtu)
{}

/*
 * Enable ECRC to align PCI-E Completion packets on an 8-byte boundary.
 * Only do it if the bridge is a root port since we don't want to disturb
 * any other device, except if forced with myri10ge_ecrc_enable > 1.
 */

static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
{}

/*
 * The Lanai Z8E PCI-E interface achieves higher Read-DMA throughput
 * when the PCI-E Completion packets are aligned on an 8-byte
 * boundary.  Some PCI-E chip sets always align Completion packets; on
 * the ones that do not, the alignment can be enforced by enabling
 * ECRC generation (if supported).
 *
 * When PCI-E Completion packets are not aligned, it is actually more
 * efficient to limit Read-DMA transactions to 2KB, rather than 4KB.
 *
 * If the driver can neither enable ECRC nor verify that it has
 * already been enabled, then it must use a firmware image which works
 * around unaligned completion packets (myri10ge_rss_ethp_z8e.dat), and it
 * should also ensure that it never gives the device a Read-DMA which is
 * larger than 2KB by setting the tx_boundary to 2KB.  If ECRC is
 * enabled, then the driver should use the aligned (myri10ge_rss_eth_z8e.dat)
 * firmware image, and set tx_boundary to 4KB.
 */

static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
{}

static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
{}

static void myri10ge_mask_surprise_down(struct pci_dev *pdev)
{}

static int __maybe_unused myri10ge_suspend(struct device *dev)
{}

static int __maybe_unused myri10ge_resume(struct device *dev)
{}

static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp)
{}

static void
myri10ge_check_slice(struct myri10ge_slice_state *ss, int *reset_needed,
		     int *busy_slice_cnt, u32 rx_pause_cnt)
{}

/*
 * This watchdog is used to check whether the board has suffered
 * from a parity error and needs to be recovered.
 */
static void myri10ge_watchdog(struct work_struct *work)
{}

/*
 * We use our own timer routine rather than relying upon
 * netdev->tx_timeout because we have a very large hardware transmit
 * queue.  Due to the large queue, the netdev->tx_timeout function
 * cannot detect a NIC with a parity error in a timely fashion if the
 * NIC is lightly loaded.
 */
static void myri10ge_watchdog_timer(struct timer_list *t)
{}

static void myri10ge_free_slices(struct myri10ge_priv *mgp)
{}

static int myri10ge_alloc_slices(struct myri10ge_priv *mgp)
{}

/*
 * This function determines the number of slices supported.
 * The number slices is the minimum of the number of CPUS,
 * the number of MSI-X irqs supported, the number of slices
 * supported by the firmware
 */
static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
{}

static const struct net_device_ops myri10ge_netdev_ops =;

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

/*
 * myri10ge_remove
 *
 * Does what is necessary to shutdown one Myrinet device. Called
 *   once for each Myrinet card by the kernel when a module is
 *   unloaded.
 */
static void myri10ge_remove(struct pci_dev *pdev)
{}

#define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E
#define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E_9

static const struct pci_device_id myri10ge_pci_tbl[] =;

MODULE_DEVICE_TABLE(pci, myri10ge_pci_tbl);

static SIMPLE_DEV_PM_OPS(myri10ge_pm_ops, myri10ge_suspend, myri10ge_resume);

static struct pci_driver myri10ge_driver =;

#ifdef CONFIG_MYRI10GE_DCA
static int
myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p)
{}

static struct notifier_block myri10ge_dca_notifier =;
#endif				/* CONFIG_MYRI10GE_DCA */

static __init int myri10ge_init_module(void)
{}

module_init();

static __exit void myri10ge_cleanup_module(void)
{}

module_exit(myri10ge_cleanup_module);