linux/drivers/net/ethernet/sfc/efx.c

// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
 * Driver for Solarflare network controllers and boards
 * Copyright 2005-2006 Fen Systems Ltd.
 * Copyright 2005-2013 Solarflare Communications Inc.
 */

#include <linux/filter.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/notifier.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
#include <linux/ethtool.h>
#include <linux/topology.h>
#include <linux/gfp.h>
#include <linux/interrupt.h>
#include "net_driver.h"
#include <net/gre.h>
#include <net/udp_tunnel.h>
#include "efx.h"
#include "efx_common.h"
#include "efx_channels.h"
#include "ef100.h"
#include "rx_common.h"
#include "tx_common.h"
#include "nic.h"
#include "io.h"
#include "selftest.h"
#include "sriov.h"
#include "efx_devlink.h"

#include "mcdi_port_common.h"
#include "mcdi_pcol.h"
#include "workarounds.h"

/**************************************************************************
 *
 * Configurable values
 *
 *************************************************************************/

module_param_named(interrupt_mode, efx_interrupt_mode, uint, 0444);
MODULE_PARM_DESC();

module_param(rss_cpus, uint, 0444);
MODULE_PARM_DESC();

/*
 * Use separate channels for TX and RX events
 *
 * Set this to 1 to use separate channels for TX and RX. It allows us
 * to control interrupt affinity separately for TX and RX.
 *
 * This is only used in MSI-X interrupt mode
 */
bool efx_separate_tx_channels;
module_param(efx_separate_tx_channels, bool, 0444);
MODULE_PARM_DESC();

/* Initial interrupt moderation settings.  They can be modified after
 * module load with ethtool.
 *
 * The default for RX should strike a balance between increasing the
 * round-trip latency and reducing overhead.
 */
static unsigned int rx_irq_mod_usec =;

/* Initial interrupt moderation settings.  They can be modified after
 * module load with ethtool.
 *
 * This default is chosen to ensure that a 10G link does not go idle
 * while a TX queue is stopped after it has become full.  A queue is
 * restarted when it drops below half full.  The time this takes (assuming
 * worst case 3 descriptors per packet and 1024 descriptors) is
 *   512 / 3 * 1.2 = 205 usec.
 */
static unsigned int tx_irq_mod_usec =;

static bool phy_flash_cfg;
module_param(phy_flash_cfg, bool, 0644);
MODULE_PARM_DESC();

static unsigned debug =;
module_param(debug, uint, 0);
MODULE_PARM_DESC();

/**************************************************************************
 *
 * Utility functions and prototypes
 *
 *************************************************************************/

static void efx_remove_port(struct efx_nic *efx);
static int efx_xdp_setup_prog(struct efx_nic *efx, struct bpf_prog *prog);
static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp);
static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs,
			u32 flags);

/**************************************************************************
 *
 * Port handling
 *
 **************************************************************************/

static void efx_fini_port(struct efx_nic *efx);

static int efx_probe_port(struct efx_nic *efx)
{}

static int efx_init_port(struct efx_nic *efx)
{}

static void efx_fini_port(struct efx_nic *efx)
{}

static void efx_remove_port(struct efx_nic *efx)
{}

/**************************************************************************
 *
 * NIC handling
 *
 **************************************************************************/

static LIST_HEAD(efx_primary_list);
static LIST_HEAD(efx_unassociated_list);

static bool efx_same_controller(struct efx_nic *left, struct efx_nic *right)
{}

static void efx_associate(struct efx_nic *efx)
{}

static void efx_dissociate(struct efx_nic *efx)
{}

static int efx_probe_nic(struct efx_nic *efx)
{}

static void efx_remove_nic(struct efx_nic *efx)
{}

/**************************************************************************
 *
 * NIC startup/shutdown
 *
 *************************************************************************/

static int efx_probe_all(struct efx_nic *efx)
{}

static void efx_remove_all(struct efx_nic *efx)
{}

/**************************************************************************
 *
 * Interrupt moderation
 *
 **************************************************************************/
unsigned int efx_usecs_to_ticks(struct efx_nic *efx, unsigned int usecs)
{}

unsigned int efx_ticks_to_usecs(struct efx_nic *efx, unsigned int ticks)
{}

/* Set interrupt moderation parameters */
int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
			    unsigned int rx_usecs, bool rx_adaptive,
			    bool rx_may_override_tx)
{}

void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
			    unsigned int *rx_usecs, bool *rx_adaptive)
{}

/**************************************************************************
 *
 * ioctls
 *
 *************************************************************************/

/* Net device ioctl
 * Context: process, rtnl_lock() held.
 */
static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
{}

/**************************************************************************
 *
 * Kernel net device interface
 *
 *************************************************************************/

/* Context: process, rtnl_lock() held. */
int efx_net_open(struct net_device *net_dev)
{}

/* Context: process, rtnl_lock() held.
 * Note that the kernel will ignore our return code; this method
 * should really be a void.
 */
int efx_net_stop(struct net_device *net_dev)
{}

static int efx_vlan_rx_add_vid(struct net_device *net_dev, __be16 proto, u16 vid)
{}

static int efx_vlan_rx_kill_vid(struct net_device *net_dev, __be16 proto, u16 vid)
{}

static int efx_hwtstamp_set(struct net_device *net_dev,
			    struct kernel_hwtstamp_config *config,
			    struct netlink_ext_ack *extack)
{}

static int efx_hwtstamp_get(struct net_device *net_dev,
			    struct kernel_hwtstamp_config *config)
{}

static const struct net_device_ops efx_netdev_ops =;

static int efx_xdp_setup_prog(struct efx_nic *efx, struct bpf_prog *prog)
{}

/* Context: process, rtnl_lock() held. */
static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{}

static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs,
			u32 flags)
{}

static void efx_update_name(struct efx_nic *efx)
{}

static int efx_netdev_event(struct notifier_block *this,
			    unsigned long event, void *ptr)
{}

static struct notifier_block efx_netdev_notifier =;

static ssize_t phy_type_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR_RO(phy_type);

static int efx_register_netdev(struct efx_nic *efx)
{}

static void efx_unregister_netdev(struct efx_nic *efx)
{}

/**************************************************************************
 *
 * List of NICs we support
 *
 **************************************************************************/

/* PCI device ID table */
static const struct pci_device_id efx_pci_table[] =;

/**************************************************************************
 *
 * Data housekeeping
 *
 **************************************************************************/

void efx_update_sw_stats(struct efx_nic *efx, u64 *stats)
{}

/**************************************************************************
 *
 * PCI interface
 *
 **************************************************************************/

/* Main body of final NIC shutdown code
 * This is called only at module unload (or hotplug removal).
 */
static void efx_pci_remove_main(struct efx_nic *efx)
{}

/* Final NIC shutdown
 * This is called only at module unload (or hotplug removal).  A PF can call
 * this on its VFs to ensure they are unbound first.
 */
static void efx_pci_remove(struct pci_dev *pci_dev)
{
	struct efx_probe_data *probe_data;
	struct efx_nic *efx;

	efx = pci_get_drvdata(pci_dev);
	if (!efx)
		return;

	/* Mark the NIC as fini, then stop the interface */
	rtnl_lock();
	efx_dissociate(efx);
	dev_close(efx->net_dev);
	efx_disable_interrupts(efx);
	efx->state = STATE_UNINIT;
	rtnl_unlock();

	if (efx->type->sriov_fini)
		efx->type->sriov_fini(efx);

	efx_fini_devlink_lock(efx);
	efx_unregister_netdev(efx);

	efx_mtd_remove(efx);

	efx_pci_remove_main(efx);

	efx_fini_io(efx);
	pci_dbg(efx->pci_dev, "shutdown successful\n");

	efx_fini_devlink_and_unlock(efx);
	efx_fini_struct(efx);
	free_netdev(efx->net_dev);
	probe_data = container_of(efx, struct efx_probe_data, efx);
	kfree(probe_data);
};

/* NIC VPD information
 * Called during probe to display the part number of the
 * installed NIC.
 */
static void efx_probe_vpd_strings(struct efx_nic *efx)
{}


/* Main body of NIC initialisation
 * This is called at module load (or hotplug insertion, theoretically).
 */
static int efx_pci_probe_main(struct efx_nic *efx)
{}

static int efx_pci_probe_post_io(struct efx_nic *efx)
{}

/* NIC initialisation
 *
 * This is called at module load (or hotplug insertion,
 * theoretically).  It sets up PCI mappings, resets the NIC,
 * sets up and registers the network devices with the kernel and hooks
 * the interrupt service routine.  It does not prepare the device for
 * transmission; this is left to the first time one of the network
 * interfaces is brought up (i.e. efx_net_open).
 */
static int efx_pci_probe(struct pci_dev *pci_dev,
			 const struct pci_device_id *entry)
{}

/* efx_pci_sriov_configure returns the actual number of Virtual Functions
 * enabled on success
 */
#ifdef CONFIG_SFC_SRIOV
static int efx_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
{}
#endif

static int efx_pm_freeze(struct device *dev)
{}

static void efx_pci_shutdown(struct pci_dev *pci_dev)
{}

static int efx_pm_thaw(struct device *dev)
{}

static int efx_pm_poweroff(struct device *dev)
{}

/* Used for both resume and restore */
static int efx_pm_resume(struct device *dev)
{}

static int efx_pm_suspend(struct device *dev)
{}

static const struct dev_pm_ops efx_pm_ops =;

static struct pci_driver efx_pci_driver =;

/**************************************************************************
 *
 * Kernel module interface
 *
 *************************************************************************/

static int __init efx_init_module(void)
{}

static void __exit efx_exit_module(void)
{}

module_init();
module_exit(efx_exit_module);

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_DEVICE_TABLE(pci, efx_pci_table);