16e173d3bSMartin Habets // SPDX-License-Identifier: GPL-2.0-only 26e173d3bSMartin Habets /**************************************************************************** 36e173d3bSMartin Habets * Driver for Solarflare network controllers and boards 46e173d3bSMartin Habets * Copyright 2005-2006 Fen Systems Ltd. 56e173d3bSMartin Habets * Copyright 2005-2013 Solarflare Communications Inc. 66e173d3bSMartin Habets */ 76e173d3bSMartin Habets 86e173d3bSMartin Habets #include <linux/filter.h> 96e173d3bSMartin Habets #include <linux/module.h> 106e173d3bSMartin Habets #include <linux/pci.h> 116e173d3bSMartin Habets #include <linux/netdevice.h> 126e173d3bSMartin Habets #include <linux/etherdevice.h> 136e173d3bSMartin Habets #include <linux/delay.h> 146e173d3bSMartin Habets #include <linux/notifier.h> 156e173d3bSMartin Habets #include <linux/ip.h> 166e173d3bSMartin Habets #include <linux/tcp.h> 176e173d3bSMartin Habets #include <linux/in.h> 186e173d3bSMartin Habets #include <linux/ethtool.h> 196e173d3bSMartin Habets #include <linux/topology.h> 206e173d3bSMartin Habets #include <linux/gfp.h> 216e173d3bSMartin Habets #include <linux/aer.h> 226e173d3bSMartin Habets #include <linux/interrupt.h> 236e173d3bSMartin Habets #include "net_driver.h" 246e173d3bSMartin Habets #include <net/gre.h> 256e173d3bSMartin Habets #include <net/udp_tunnel.h> 266e173d3bSMartin Habets #include "efx.h" 276e173d3bSMartin Habets #include "efx_common.h" 286e173d3bSMartin Habets #include "efx_channels.h" 296e173d3bSMartin Habets #include "rx_common.h" 306e173d3bSMartin Habets #include "tx_common.h" 316e173d3bSMartin Habets #include "nic.h" 326e173d3bSMartin Habets #include "io.h" 336e173d3bSMartin Habets #include "selftest.h" 346e173d3bSMartin Habets #include "sriov.h" 35*c3743039SMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 36*c3743039SMartin Habets #include "siena_sriov.h" 37*c3743039SMartin Habets #endif 386e173d3bSMartin Habets 396e173d3bSMartin Habets #include "mcdi_port_common.h" 406e173d3bSMartin Habets #include "mcdi_pcol.h" 416e173d3bSMartin Habets #include "workarounds.h" 426e173d3bSMartin Habets 436e173d3bSMartin Habets /************************************************************************** 446e173d3bSMartin Habets * 456e173d3bSMartin Habets * Configurable values 466e173d3bSMartin Habets * 476e173d3bSMartin Habets *************************************************************************/ 486e173d3bSMartin Habets 4971ad88f6SMartin Habets module_param_named(interrupt_mode, efx_siena_interrupt_mode, uint, 0444); 506e173d3bSMartin Habets MODULE_PARM_DESC(interrupt_mode, 516e173d3bSMartin Habets "Interrupt mode (0=>MSIX 1=>MSI 2=>legacy)"); 526e173d3bSMartin Habets 5371ad88f6SMartin Habets module_param_named(rss_cpus, efx_siena_rss_cpus, uint, 0444); 546e173d3bSMartin Habets MODULE_PARM_DESC(rss_cpus, "Number of CPUs to use for Receive-Side Scaling"); 556e173d3bSMartin Habets 566e173d3bSMartin Habets /* 576e173d3bSMartin Habets * Use separate channels for TX and RX events 586e173d3bSMartin Habets * 596e173d3bSMartin Habets * Set this to 1 to use separate channels for TX and RX. It allows us 606e173d3bSMartin Habets * to control interrupt affinity separately for TX and RX. 616e173d3bSMartin Habets * 626e173d3bSMartin Habets * This is only used in MSI-X interrupt mode 636e173d3bSMartin Habets */ 647f9e4b2aSMartin Habets bool efx_siena_separate_tx_channels; 657f9e4b2aSMartin Habets module_param_named(efx_separate_tx_channels, efx_siena_separate_tx_channels, 667f9e4b2aSMartin Habets bool, 0444); 676e173d3bSMartin Habets MODULE_PARM_DESC(efx_separate_tx_channels, 686e173d3bSMartin Habets "Use separate channels for TX and RX"); 696e173d3bSMartin Habets 706e173d3bSMartin Habets /* Initial interrupt moderation settings. They can be modified after 716e173d3bSMartin Habets * module load with ethtool. 726e173d3bSMartin Habets * 736e173d3bSMartin Habets * The default for RX should strike a balance between increasing the 746e173d3bSMartin Habets * round-trip latency and reducing overhead. 756e173d3bSMartin Habets */ 766e173d3bSMartin Habets static unsigned int rx_irq_mod_usec = 60; 776e173d3bSMartin Habets 786e173d3bSMartin Habets /* Initial interrupt moderation settings. They can be modified after 796e173d3bSMartin Habets * module load with ethtool. 806e173d3bSMartin Habets * 816e173d3bSMartin Habets * This default is chosen to ensure that a 10G link does not go idle 826e173d3bSMartin Habets * while a TX queue is stopped after it has become full. A queue is 836e173d3bSMartin Habets * restarted when it drops below half full. The time this takes (assuming 846e173d3bSMartin Habets * worst case 3 descriptors per packet and 1024 descriptors) is 856e173d3bSMartin Habets * 512 / 3 * 1.2 = 205 usec. 866e173d3bSMartin Habets */ 876e173d3bSMartin Habets static unsigned int tx_irq_mod_usec = 150; 886e173d3bSMartin Habets 896e173d3bSMartin Habets static bool phy_flash_cfg; 906e173d3bSMartin Habets module_param(phy_flash_cfg, bool, 0644); 916e173d3bSMartin Habets MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially"); 926e173d3bSMartin Habets 936e173d3bSMartin Habets static unsigned debug = (NETIF_MSG_DRV | NETIF_MSG_PROBE | 946e173d3bSMartin Habets NETIF_MSG_LINK | NETIF_MSG_IFDOWN | 956e173d3bSMartin Habets NETIF_MSG_IFUP | NETIF_MSG_RX_ERR | 966e173d3bSMartin Habets NETIF_MSG_TX_ERR | NETIF_MSG_HW); 976e173d3bSMartin Habets module_param(debug, uint, 0); 986e173d3bSMartin Habets MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value"); 996e173d3bSMartin Habets 1006e173d3bSMartin Habets /************************************************************************** 1016e173d3bSMartin Habets * 1026e173d3bSMartin Habets * Utility functions and prototypes 1036e173d3bSMartin Habets * 1046e173d3bSMartin Habets *************************************************************************/ 1056e173d3bSMartin Habets 1066e173d3bSMartin Habets static void efx_remove_port(struct efx_nic *efx); 1076e173d3bSMartin Habets static int efx_xdp_setup_prog(struct efx_nic *efx, struct bpf_prog *prog); 1086e173d3bSMartin Habets static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp); 1096e173d3bSMartin Habets static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs, 1106e173d3bSMartin Habets u32 flags); 1116e173d3bSMartin Habets 1126e173d3bSMartin Habets #define EFX_ASSERT_RESET_SERIALISED(efx) \ 1136e173d3bSMartin Habets do { \ 1146e173d3bSMartin Habets if ((efx->state == STATE_READY) || \ 1156e173d3bSMartin Habets (efx->state == STATE_RECOVERY) || \ 1166e173d3bSMartin Habets (efx->state == STATE_DISABLED)) \ 1176e173d3bSMartin Habets ASSERT_RTNL(); \ 1186e173d3bSMartin Habets } while (0) 1196e173d3bSMartin Habets 1206e173d3bSMartin Habets /************************************************************************** 1216e173d3bSMartin Habets * 1226e173d3bSMartin Habets * Port handling 1236e173d3bSMartin Habets * 1246e173d3bSMartin Habets **************************************************************************/ 1256e173d3bSMartin Habets 1266e173d3bSMartin Habets static void efx_fini_port(struct efx_nic *efx); 1276e173d3bSMartin Habets 1286e173d3bSMartin Habets static int efx_probe_port(struct efx_nic *efx) 1296e173d3bSMartin Habets { 1306e173d3bSMartin Habets int rc; 1316e173d3bSMartin Habets 1326e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev, "create port\n"); 1336e173d3bSMartin Habets 1346e173d3bSMartin Habets if (phy_flash_cfg) 1356e173d3bSMartin Habets efx->phy_mode = PHY_MODE_SPECIAL; 1366e173d3bSMartin Habets 1376e173d3bSMartin Habets /* Connect up MAC/PHY operations table */ 1386e173d3bSMartin Habets rc = efx->type->probe_port(efx); 1396e173d3bSMartin Habets if (rc) 1406e173d3bSMartin Habets return rc; 1416e173d3bSMartin Habets 1426e173d3bSMartin Habets /* Initialise MAC address to permanent address */ 1436e173d3bSMartin Habets eth_hw_addr_set(efx->net_dev, efx->net_dev->perm_addr); 1446e173d3bSMartin Habets 1456e173d3bSMartin Habets return 0; 1466e173d3bSMartin Habets } 1476e173d3bSMartin Habets 1486e173d3bSMartin Habets static int efx_init_port(struct efx_nic *efx) 1496e173d3bSMartin Habets { 1506e173d3bSMartin Habets int rc; 1516e173d3bSMartin Habets 1526e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "init port\n"); 1536e173d3bSMartin Habets 1546e173d3bSMartin Habets mutex_lock(&efx->mac_lock); 1556e173d3bSMartin Habets 1566e173d3bSMartin Habets efx->port_initialized = true; 1576e173d3bSMartin Habets 1586e173d3bSMartin Habets /* Ensure the PHY advertises the correct flow control settings */ 1594d49e5cdSMartin Habets rc = efx_siena_mcdi_port_reconfigure(efx); 1606e173d3bSMartin Habets if (rc && rc != -EPERM) 1616e173d3bSMartin Habets goto fail; 1626e173d3bSMartin Habets 1636e173d3bSMartin Habets mutex_unlock(&efx->mac_lock); 1646e173d3bSMartin Habets return 0; 1656e173d3bSMartin Habets 1666e173d3bSMartin Habets fail: 1676e173d3bSMartin Habets mutex_unlock(&efx->mac_lock); 1686e173d3bSMartin Habets return rc; 1696e173d3bSMartin Habets } 1706e173d3bSMartin Habets 1716e173d3bSMartin Habets static void efx_fini_port(struct efx_nic *efx) 1726e173d3bSMartin Habets { 1736e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "shut down port\n"); 1746e173d3bSMartin Habets 1756e173d3bSMartin Habets if (!efx->port_initialized) 1766e173d3bSMartin Habets return; 1776e173d3bSMartin Habets 1786e173d3bSMartin Habets efx->port_initialized = false; 1796e173d3bSMartin Habets 1806e173d3bSMartin Habets efx->link_state.up = false; 18171ad88f6SMartin Habets efx_siena_link_status_changed(efx); 1826e173d3bSMartin Habets } 1836e173d3bSMartin Habets 1846e173d3bSMartin Habets static void efx_remove_port(struct efx_nic *efx) 1856e173d3bSMartin Habets { 1866e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "destroying port\n"); 1876e173d3bSMartin Habets 1886e173d3bSMartin Habets efx->type->remove_port(efx); 1896e173d3bSMartin Habets } 1906e173d3bSMartin Habets 1916e173d3bSMartin Habets /************************************************************************** 1926e173d3bSMartin Habets * 1936e173d3bSMartin Habets * NIC handling 1946e173d3bSMartin Habets * 1956e173d3bSMartin Habets **************************************************************************/ 1966e173d3bSMartin Habets 1976e173d3bSMartin Habets static LIST_HEAD(efx_primary_list); 1986e173d3bSMartin Habets static LIST_HEAD(efx_unassociated_list); 1996e173d3bSMartin Habets 2006e173d3bSMartin Habets static bool efx_same_controller(struct efx_nic *left, struct efx_nic *right) 2016e173d3bSMartin Habets { 2026e173d3bSMartin Habets return left->type == right->type && 2036e173d3bSMartin Habets left->vpd_sn && right->vpd_sn && 2046e173d3bSMartin Habets !strcmp(left->vpd_sn, right->vpd_sn); 2056e173d3bSMartin Habets } 2066e173d3bSMartin Habets 2076e173d3bSMartin Habets static void efx_associate(struct efx_nic *efx) 2086e173d3bSMartin Habets { 2096e173d3bSMartin Habets struct efx_nic *other, *next; 2106e173d3bSMartin Habets 2116e173d3bSMartin Habets if (efx->primary == efx) { 2126e173d3bSMartin Habets /* Adding primary function; look for secondaries */ 2136e173d3bSMartin Habets 2146e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev, "adding to primary list\n"); 2156e173d3bSMartin Habets list_add_tail(&efx->node, &efx_primary_list); 2166e173d3bSMartin Habets 2176e173d3bSMartin Habets list_for_each_entry_safe(other, next, &efx_unassociated_list, 2186e173d3bSMartin Habets node) { 2196e173d3bSMartin Habets if (efx_same_controller(efx, other)) { 2206e173d3bSMartin Habets list_del(&other->node); 2216e173d3bSMartin Habets netif_dbg(other, probe, other->net_dev, 2226e173d3bSMartin Habets "moving to secondary list of %s %s\n", 2236e173d3bSMartin Habets pci_name(efx->pci_dev), 2246e173d3bSMartin Habets efx->net_dev->name); 2256e173d3bSMartin Habets list_add_tail(&other->node, 2266e173d3bSMartin Habets &efx->secondary_list); 2276e173d3bSMartin Habets other->primary = efx; 2286e173d3bSMartin Habets } 2296e173d3bSMartin Habets } 2306e173d3bSMartin Habets } else { 2316e173d3bSMartin Habets /* Adding secondary function; look for primary */ 2326e173d3bSMartin Habets 2336e173d3bSMartin Habets list_for_each_entry(other, &efx_primary_list, node) { 2346e173d3bSMartin Habets if (efx_same_controller(efx, other)) { 2356e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev, 2366e173d3bSMartin Habets "adding to secondary list of %s %s\n", 2376e173d3bSMartin Habets pci_name(other->pci_dev), 2386e173d3bSMartin Habets other->net_dev->name); 2396e173d3bSMartin Habets list_add_tail(&efx->node, 2406e173d3bSMartin Habets &other->secondary_list); 2416e173d3bSMartin Habets efx->primary = other; 2426e173d3bSMartin Habets return; 2436e173d3bSMartin Habets } 2446e173d3bSMartin Habets } 2456e173d3bSMartin Habets 2466e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev, 2476e173d3bSMartin Habets "adding to unassociated list\n"); 2486e173d3bSMartin Habets list_add_tail(&efx->node, &efx_unassociated_list); 2496e173d3bSMartin Habets } 2506e173d3bSMartin Habets } 2516e173d3bSMartin Habets 2526e173d3bSMartin Habets static void efx_dissociate(struct efx_nic *efx) 2536e173d3bSMartin Habets { 2546e173d3bSMartin Habets struct efx_nic *other, *next; 2556e173d3bSMartin Habets 2566e173d3bSMartin Habets list_del(&efx->node); 2576e173d3bSMartin Habets efx->primary = NULL; 2586e173d3bSMartin Habets 2596e173d3bSMartin Habets list_for_each_entry_safe(other, next, &efx->secondary_list, node) { 2606e173d3bSMartin Habets list_del(&other->node); 2616e173d3bSMartin Habets netif_dbg(other, probe, other->net_dev, 2626e173d3bSMartin Habets "moving to unassociated list\n"); 2636e173d3bSMartin Habets list_add_tail(&other->node, &efx_unassociated_list); 2646e173d3bSMartin Habets other->primary = NULL; 2656e173d3bSMartin Habets } 2666e173d3bSMartin Habets } 2676e173d3bSMartin Habets 2686e173d3bSMartin Habets static int efx_probe_nic(struct efx_nic *efx) 2696e173d3bSMartin Habets { 2706e173d3bSMartin Habets int rc; 2716e173d3bSMartin Habets 2726e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev, "creating NIC\n"); 2736e173d3bSMartin Habets 2746e173d3bSMartin Habets /* Carry out hardware-type specific initialisation */ 2756e173d3bSMartin Habets rc = efx->type->probe(efx); 2766e173d3bSMartin Habets if (rc) 2776e173d3bSMartin Habets return rc; 2786e173d3bSMartin Habets 2796e173d3bSMartin Habets do { 2806e173d3bSMartin Habets if (!efx->max_channels || !efx->max_tx_channels) { 2816e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, 2826e173d3bSMartin Habets "Insufficient resources to allocate" 2836e173d3bSMartin Habets " any channels\n"); 2846e173d3bSMartin Habets rc = -ENOSPC; 2856e173d3bSMartin Habets goto fail1; 2866e173d3bSMartin Habets } 2876e173d3bSMartin Habets 2886e173d3bSMartin Habets /* Determine the number of channels and queues by trying 2896e173d3bSMartin Habets * to hook in MSI-X interrupts. 2906e173d3bSMartin Habets */ 29171ad88f6SMartin Habets rc = efx_siena_probe_interrupts(efx); 2926e173d3bSMartin Habets if (rc) 2936e173d3bSMartin Habets goto fail1; 2946e173d3bSMartin Habets 29571ad88f6SMartin Habets rc = efx_siena_set_channels(efx); 2966e173d3bSMartin Habets if (rc) 2976e173d3bSMartin Habets goto fail1; 2986e173d3bSMartin Habets 2996e173d3bSMartin Habets /* dimension_resources can fail with EAGAIN */ 3006e173d3bSMartin Habets rc = efx->type->dimension_resources(efx); 3016e173d3bSMartin Habets if (rc != 0 && rc != -EAGAIN) 3026e173d3bSMartin Habets goto fail2; 3036e173d3bSMartin Habets 3046e173d3bSMartin Habets if (rc == -EAGAIN) 3056e173d3bSMartin Habets /* try again with new max_channels */ 30671ad88f6SMartin Habets efx_siena_remove_interrupts(efx); 3076e173d3bSMartin Habets 3086e173d3bSMartin Habets } while (rc == -EAGAIN); 3096e173d3bSMartin Habets 3106e173d3bSMartin Habets if (efx->n_channels > 1) 3116e173d3bSMartin Habets netdev_rss_key_fill(efx->rss_context.rx_hash_key, 3126e173d3bSMartin Habets sizeof(efx->rss_context.rx_hash_key)); 3137f9e4b2aSMartin Habets efx_siena_set_default_rx_indir_table(efx, &efx->rss_context); 3146e173d3bSMartin Habets 3156e173d3bSMartin Habets /* Initialise the interrupt moderation settings */ 3166e173d3bSMartin Habets efx->irq_mod_step_us = DIV_ROUND_UP(efx->timer_quantum_ns, 1000); 31771ad88f6SMartin Habets efx_siena_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, 31871ad88f6SMartin Habets true, true); 3196e173d3bSMartin Habets 3206e173d3bSMartin Habets return 0; 3216e173d3bSMartin Habets 3226e173d3bSMartin Habets fail2: 32371ad88f6SMartin Habets efx_siena_remove_interrupts(efx); 3246e173d3bSMartin Habets fail1: 3256e173d3bSMartin Habets efx->type->remove(efx); 3266e173d3bSMartin Habets return rc; 3276e173d3bSMartin Habets } 3286e173d3bSMartin Habets 3296e173d3bSMartin Habets static void efx_remove_nic(struct efx_nic *efx) 3306e173d3bSMartin Habets { 3316e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "destroying NIC\n"); 3326e173d3bSMartin Habets 33371ad88f6SMartin Habets efx_siena_remove_interrupts(efx); 3346e173d3bSMartin Habets efx->type->remove(efx); 3356e173d3bSMartin Habets } 3366e173d3bSMartin Habets 3376e173d3bSMartin Habets /************************************************************************** 3386e173d3bSMartin Habets * 3396e173d3bSMartin Habets * NIC startup/shutdown 3406e173d3bSMartin Habets * 3416e173d3bSMartin Habets *************************************************************************/ 3426e173d3bSMartin Habets 3436e173d3bSMartin Habets static int efx_probe_all(struct efx_nic *efx) 3446e173d3bSMartin Habets { 3456e173d3bSMartin Habets int rc; 3466e173d3bSMartin Habets 3476e173d3bSMartin Habets rc = efx_probe_nic(efx); 3486e173d3bSMartin Habets if (rc) { 3496e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev, "failed to create NIC\n"); 3506e173d3bSMartin Habets goto fail1; 3516e173d3bSMartin Habets } 3526e173d3bSMartin Habets 3536e173d3bSMartin Habets rc = efx_probe_port(efx); 3546e173d3bSMartin Habets if (rc) { 3556e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev, "failed to create port\n"); 3566e173d3bSMartin Habets goto fail2; 3576e173d3bSMartin Habets } 3586e173d3bSMartin Habets 3596e173d3bSMartin Habets BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT); 3606e173d3bSMartin Habets if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) { 3616e173d3bSMartin Habets rc = -EINVAL; 3626e173d3bSMartin Habets goto fail3; 3636e173d3bSMartin Habets } 3646e173d3bSMartin Habets 365dfb1cfbdSMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 3666e173d3bSMartin Habets rc = efx->type->vswitching_probe(efx); 3676e173d3bSMartin Habets if (rc) /* not fatal; the PF will still work fine */ 3686e173d3bSMartin Habets netif_warn(efx, probe, efx->net_dev, 3696e173d3bSMartin Habets "failed to setup vswitching rc=%d;" 3706e173d3bSMartin Habets " VFs may not function\n", rc); 3716e173d3bSMartin Habets #endif 3726e173d3bSMartin Habets 3737f9e4b2aSMartin Habets rc = efx_siena_probe_filters(efx); 3746e173d3bSMartin Habets if (rc) { 3756e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev, 3766e173d3bSMartin Habets "failed to create filter tables\n"); 3776e173d3bSMartin Habets goto fail4; 3786e173d3bSMartin Habets } 3796e173d3bSMartin Habets 38071ad88f6SMartin Habets rc = efx_siena_probe_channels(efx); 3816e173d3bSMartin Habets if (rc) 3826e173d3bSMartin Habets goto fail5; 3836e173d3bSMartin Habets 3846e173d3bSMartin Habets return 0; 3856e173d3bSMartin Habets 3866e173d3bSMartin Habets fail5: 3877f9e4b2aSMartin Habets efx_siena_remove_filters(efx); 3886e173d3bSMartin Habets fail4: 389dfb1cfbdSMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 3906e173d3bSMartin Habets efx->type->vswitching_remove(efx); 3916e173d3bSMartin Habets #endif 3926e173d3bSMartin Habets fail3: 3936e173d3bSMartin Habets efx_remove_port(efx); 3946e173d3bSMartin Habets fail2: 3956e173d3bSMartin Habets efx_remove_nic(efx); 3966e173d3bSMartin Habets fail1: 3976e173d3bSMartin Habets return rc; 3986e173d3bSMartin Habets } 3996e173d3bSMartin Habets 4006e173d3bSMartin Habets static void efx_remove_all(struct efx_nic *efx) 4016e173d3bSMartin Habets { 4026e173d3bSMartin Habets rtnl_lock(); 4036e173d3bSMartin Habets efx_xdp_setup_prog(efx, NULL); 4046e173d3bSMartin Habets rtnl_unlock(); 4056e173d3bSMartin Habets 40671ad88f6SMartin Habets efx_siena_remove_channels(efx); 4077f9e4b2aSMartin Habets efx_siena_remove_filters(efx); 408dfb1cfbdSMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 4096e173d3bSMartin Habets efx->type->vswitching_remove(efx); 4106e173d3bSMartin Habets #endif 4116e173d3bSMartin Habets efx_remove_port(efx); 4126e173d3bSMartin Habets efx_remove_nic(efx); 4136e173d3bSMartin Habets } 4146e173d3bSMartin Habets 4156e173d3bSMartin Habets /************************************************************************** 4166e173d3bSMartin Habets * 4176e173d3bSMartin Habets * Interrupt moderation 4186e173d3bSMartin Habets * 4196e173d3bSMartin Habets **************************************************************************/ 42071ad88f6SMartin Habets unsigned int efx_siena_usecs_to_ticks(struct efx_nic *efx, unsigned int usecs) 4216e173d3bSMartin Habets { 4226e173d3bSMartin Habets if (usecs == 0) 4236e173d3bSMartin Habets return 0; 4246e173d3bSMartin Habets if (usecs * 1000 < efx->timer_quantum_ns) 4256e173d3bSMartin Habets return 1; /* never round down to 0 */ 4266e173d3bSMartin Habets return usecs * 1000 / efx->timer_quantum_ns; 4276e173d3bSMartin Habets } 4286e173d3bSMartin Habets 4296e173d3bSMartin Habets /* Set interrupt moderation parameters */ 43071ad88f6SMartin Habets int efx_siena_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, 4316e173d3bSMartin Habets unsigned int rx_usecs, bool rx_adaptive, 4326e173d3bSMartin Habets bool rx_may_override_tx) 4336e173d3bSMartin Habets { 4346e173d3bSMartin Habets struct efx_channel *channel; 4356e173d3bSMartin Habets unsigned int timer_max_us; 4366e173d3bSMartin Habets 4376e173d3bSMartin Habets EFX_ASSERT_RESET_SERIALISED(efx); 4386e173d3bSMartin Habets 4396e173d3bSMartin Habets timer_max_us = efx->timer_max_ns / 1000; 4406e173d3bSMartin Habets 4416e173d3bSMartin Habets if (tx_usecs > timer_max_us || rx_usecs > timer_max_us) 4426e173d3bSMartin Habets return -EINVAL; 4436e173d3bSMartin Habets 4446e173d3bSMartin Habets if (tx_usecs != rx_usecs && efx->tx_channel_offset == 0 && 4456e173d3bSMartin Habets !rx_may_override_tx) { 4466e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, "Channels are shared. " 4476e173d3bSMartin Habets "RX and TX IRQ moderation must be equal\n"); 4486e173d3bSMartin Habets return -EINVAL; 4496e173d3bSMartin Habets } 4506e173d3bSMartin Habets 4516e173d3bSMartin Habets efx->irq_rx_adaptive = rx_adaptive; 4526e173d3bSMartin Habets efx->irq_rx_moderation_us = rx_usecs; 4536e173d3bSMartin Habets efx_for_each_channel(channel, efx) { 4546e173d3bSMartin Habets if (efx_channel_has_rx_queue(channel)) 4556e173d3bSMartin Habets channel->irq_moderation_us = rx_usecs; 4566e173d3bSMartin Habets else if (efx_channel_has_tx_queues(channel)) 4576e173d3bSMartin Habets channel->irq_moderation_us = tx_usecs; 4586e173d3bSMartin Habets else if (efx_channel_is_xdp_tx(channel)) 4596e173d3bSMartin Habets channel->irq_moderation_us = tx_usecs; 4606e173d3bSMartin Habets } 4616e173d3bSMartin Habets 4626e173d3bSMartin Habets return 0; 4636e173d3bSMartin Habets } 4646e173d3bSMartin Habets 46571ad88f6SMartin Habets void efx_siena_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, 4666e173d3bSMartin Habets unsigned int *rx_usecs, bool *rx_adaptive) 4676e173d3bSMartin Habets { 4686e173d3bSMartin Habets *rx_adaptive = efx->irq_rx_adaptive; 4696e173d3bSMartin Habets *rx_usecs = efx->irq_rx_moderation_us; 4706e173d3bSMartin Habets 4716e173d3bSMartin Habets /* If channels are shared between RX and TX, so is IRQ 4726e173d3bSMartin Habets * moderation. Otherwise, IRQ moderation is the same for all 4736e173d3bSMartin Habets * TX channels and is not adaptive. 4746e173d3bSMartin Habets */ 4756e173d3bSMartin Habets if (efx->tx_channel_offset == 0) { 4766e173d3bSMartin Habets *tx_usecs = *rx_usecs; 4776e173d3bSMartin Habets } else { 4786e173d3bSMartin Habets struct efx_channel *tx_channel; 4796e173d3bSMartin Habets 4806e173d3bSMartin Habets tx_channel = efx->channel[efx->tx_channel_offset]; 4816e173d3bSMartin Habets *tx_usecs = tx_channel->irq_moderation_us; 4826e173d3bSMartin Habets } 4836e173d3bSMartin Habets } 4846e173d3bSMartin Habets 4856e173d3bSMartin Habets /************************************************************************** 4866e173d3bSMartin Habets * 4876e173d3bSMartin Habets * ioctls 4886e173d3bSMartin Habets * 4896e173d3bSMartin Habets *************************************************************************/ 4906e173d3bSMartin Habets 4916e173d3bSMartin Habets /* Net device ioctl 4926e173d3bSMartin Habets * Context: process, rtnl_lock() held. 4936e173d3bSMartin Habets */ 4946e173d3bSMartin Habets static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) 4956e173d3bSMartin Habets { 4966e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev); 4976e173d3bSMartin Habets struct mii_ioctl_data *data = if_mii(ifr); 4986e173d3bSMartin Habets 4996e173d3bSMartin Habets if (cmd == SIOCSHWTSTAMP) 50095e96f77SMartin Habets return efx_siena_ptp_set_ts_config(efx, ifr); 5016e173d3bSMartin Habets if (cmd == SIOCGHWTSTAMP) 50295e96f77SMartin Habets return efx_siena_ptp_get_ts_config(efx, ifr); 5036e173d3bSMartin Habets 5046e173d3bSMartin Habets /* Convert phy_id from older PRTAD/DEVAD format */ 5056e173d3bSMartin Habets if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) && 5066e173d3bSMartin Habets (data->phy_id & 0xfc00) == 0x0400) 5076e173d3bSMartin Habets data->phy_id ^= MDIO_PHY_ID_C45 | 0x0400; 5086e173d3bSMartin Habets 5096e173d3bSMartin Habets return mdio_mii_ioctl(&efx->mdio, data, cmd); 5106e173d3bSMartin Habets } 5116e173d3bSMartin Habets 5126e173d3bSMartin Habets /************************************************************************** 5136e173d3bSMartin Habets * 5146e173d3bSMartin Habets * Kernel net device interface 5156e173d3bSMartin Habets * 5166e173d3bSMartin Habets *************************************************************************/ 5176e173d3bSMartin Habets 5186e173d3bSMartin Habets /* Context: process, rtnl_lock() held. */ 51971ad88f6SMartin Habets static int efx_net_open(struct net_device *net_dev) 5206e173d3bSMartin Habets { 5216e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev); 5226e173d3bSMartin Habets int rc; 5236e173d3bSMartin Habets 5246e173d3bSMartin Habets netif_dbg(efx, ifup, efx->net_dev, "opening device on CPU %d\n", 5256e173d3bSMartin Habets raw_smp_processor_id()); 5266e173d3bSMartin Habets 5276e173d3bSMartin Habets rc = efx_check_disabled(efx); 5286e173d3bSMartin Habets if (rc) 5296e173d3bSMartin Habets return rc; 5306e173d3bSMartin Habets if (efx->phy_mode & PHY_MODE_SPECIAL) 5316e173d3bSMartin Habets return -EBUSY; 5324d49e5cdSMartin Habets if (efx_siena_mcdi_poll_reboot(efx) && efx_siena_reset(efx, RESET_TYPE_ALL)) 5336e173d3bSMartin Habets return -EIO; 5346e173d3bSMartin Habets 5356e173d3bSMartin Habets /* Notify the kernel of the link state polled during driver load, 5366e173d3bSMartin Habets * before the monitor starts running */ 53771ad88f6SMartin Habets efx_siena_link_status_changed(efx); 5386e173d3bSMartin Habets 53971ad88f6SMartin Habets efx_siena_start_all(efx); 5406e173d3bSMartin Habets if (efx->state == STATE_DISABLED || efx->reset_pending) 5416e173d3bSMartin Habets netif_device_detach(efx->net_dev); 54295e96f77SMartin Habets efx_siena_selftest_async_start(efx); 5436e173d3bSMartin Habets return 0; 5446e173d3bSMartin Habets } 5456e173d3bSMartin Habets 5466e173d3bSMartin Habets /* Context: process, rtnl_lock() held. 5476e173d3bSMartin Habets * Note that the kernel will ignore our return code; this method 5486e173d3bSMartin Habets * should really be a void. 5496e173d3bSMartin Habets */ 55071ad88f6SMartin Habets static int efx_net_stop(struct net_device *net_dev) 5516e173d3bSMartin Habets { 5526e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev); 5536e173d3bSMartin Habets 5546e173d3bSMartin Habets netif_dbg(efx, ifdown, efx->net_dev, "closing on CPU %d\n", 5556e173d3bSMartin Habets raw_smp_processor_id()); 5566e173d3bSMartin Habets 5576e173d3bSMartin Habets /* Stop the device and flush all the channels */ 55871ad88f6SMartin Habets efx_siena_stop_all(efx); 5596e173d3bSMartin Habets 5606e173d3bSMartin Habets return 0; 5616e173d3bSMartin Habets } 5626e173d3bSMartin Habets 5636e173d3bSMartin Habets static int efx_vlan_rx_add_vid(struct net_device *net_dev, __be16 proto, u16 vid) 5646e173d3bSMartin Habets { 5656e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev); 5666e173d3bSMartin Habets 5676e173d3bSMartin Habets if (efx->type->vlan_rx_add_vid) 5686e173d3bSMartin Habets return efx->type->vlan_rx_add_vid(efx, proto, vid); 5696e173d3bSMartin Habets else 5706e173d3bSMartin Habets return -EOPNOTSUPP; 5716e173d3bSMartin Habets } 5726e173d3bSMartin Habets 5736e173d3bSMartin Habets static int efx_vlan_rx_kill_vid(struct net_device *net_dev, __be16 proto, u16 vid) 5746e173d3bSMartin Habets { 5756e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev); 5766e173d3bSMartin Habets 5776e173d3bSMartin Habets if (efx->type->vlan_rx_kill_vid) 5786e173d3bSMartin Habets return efx->type->vlan_rx_kill_vid(efx, proto, vid); 5796e173d3bSMartin Habets else 5806e173d3bSMartin Habets return -EOPNOTSUPP; 5816e173d3bSMartin Habets } 5826e173d3bSMartin Habets 5836e173d3bSMartin Habets static const struct net_device_ops efx_netdev_ops = { 5846e173d3bSMartin Habets .ndo_open = efx_net_open, 5856e173d3bSMartin Habets .ndo_stop = efx_net_stop, 58671ad88f6SMartin Habets .ndo_get_stats64 = efx_siena_net_stats, 58771ad88f6SMartin Habets .ndo_tx_timeout = efx_siena_watchdog, 58871ad88f6SMartin Habets .ndo_start_xmit = efx_siena_hard_start_xmit, 5896e173d3bSMartin Habets .ndo_validate_addr = eth_validate_addr, 5906e173d3bSMartin Habets .ndo_eth_ioctl = efx_ioctl, 59171ad88f6SMartin Habets .ndo_change_mtu = efx_siena_change_mtu, 59271ad88f6SMartin Habets .ndo_set_mac_address = efx_siena_set_mac_address, 59371ad88f6SMartin Habets .ndo_set_rx_mode = efx_siena_set_rx_mode, 59471ad88f6SMartin Habets .ndo_set_features = efx_siena_set_features, 59571ad88f6SMartin Habets .ndo_features_check = efx_siena_features_check, 5966e173d3bSMartin Habets .ndo_vlan_rx_add_vid = efx_vlan_rx_add_vid, 5976e173d3bSMartin Habets .ndo_vlan_rx_kill_vid = efx_vlan_rx_kill_vid, 598dfb1cfbdSMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 5996e173d3bSMartin Habets .ndo_set_vf_mac = efx_sriov_set_vf_mac, 6006e173d3bSMartin Habets .ndo_set_vf_vlan = efx_sriov_set_vf_vlan, 6016e173d3bSMartin Habets .ndo_set_vf_spoofchk = efx_sriov_set_vf_spoofchk, 6026e173d3bSMartin Habets .ndo_get_vf_config = efx_sriov_get_vf_config, 6036e173d3bSMartin Habets .ndo_set_vf_link_state = efx_sriov_set_vf_link_state, 6046e173d3bSMartin Habets #endif 60571ad88f6SMartin Habets .ndo_get_phys_port_id = efx_siena_get_phys_port_id, 60671ad88f6SMartin Habets .ndo_get_phys_port_name = efx_siena_get_phys_port_name, 60771ad88f6SMartin Habets .ndo_setup_tc = efx_siena_setup_tc, 6086e173d3bSMartin Habets #ifdef CONFIG_RFS_ACCEL 6097f9e4b2aSMartin Habets .ndo_rx_flow_steer = efx_siena_filter_rfs, 6106e173d3bSMartin Habets #endif 6116e173d3bSMartin Habets .ndo_xdp_xmit = efx_xdp_xmit, 6126e173d3bSMartin Habets .ndo_bpf = efx_xdp 6136e173d3bSMartin Habets }; 6146e173d3bSMartin Habets 6156e173d3bSMartin Habets static int efx_xdp_setup_prog(struct efx_nic *efx, struct bpf_prog *prog) 6166e173d3bSMartin Habets { 6176e173d3bSMartin Habets struct bpf_prog *old_prog; 6186e173d3bSMartin Habets 6196e173d3bSMartin Habets if (efx->xdp_rxq_info_failed) { 6206e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, 6216e173d3bSMartin Habets "Unable to bind XDP program due to previous failure of rxq_info\n"); 6226e173d3bSMartin Habets return -EINVAL; 6236e173d3bSMartin Habets } 6246e173d3bSMartin Habets 62571ad88f6SMartin Habets if (prog && efx->net_dev->mtu > efx_siena_xdp_max_mtu(efx)) { 6266e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, 6276e173d3bSMartin Habets "Unable to configure XDP with MTU of %d (max: %d)\n", 62871ad88f6SMartin Habets efx->net_dev->mtu, efx_siena_xdp_max_mtu(efx)); 6296e173d3bSMartin Habets return -EINVAL; 6306e173d3bSMartin Habets } 6316e173d3bSMartin Habets 6326e173d3bSMartin Habets old_prog = rtnl_dereference(efx->xdp_prog); 6336e173d3bSMartin Habets rcu_assign_pointer(efx->xdp_prog, prog); 6346e173d3bSMartin Habets /* Release the reference that was originally passed by the caller. */ 6356e173d3bSMartin Habets if (old_prog) 6366e173d3bSMartin Habets bpf_prog_put(old_prog); 6376e173d3bSMartin Habets 6386e173d3bSMartin Habets return 0; 6396e173d3bSMartin Habets } 6406e173d3bSMartin Habets 6416e173d3bSMartin Habets /* Context: process, rtnl_lock() held. */ 6426e173d3bSMartin Habets static int efx_xdp(struct net_device *dev, struct netdev_bpf *xdp) 6436e173d3bSMartin Habets { 6446e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(dev); 6456e173d3bSMartin Habets 6466e173d3bSMartin Habets switch (xdp->command) { 6476e173d3bSMartin Habets case XDP_SETUP_PROG: 6486e173d3bSMartin Habets return efx_xdp_setup_prog(efx, xdp->prog); 6496e173d3bSMartin Habets default: 6506e173d3bSMartin Habets return -EINVAL; 6516e173d3bSMartin Habets } 6526e173d3bSMartin Habets } 6536e173d3bSMartin Habets 6546e173d3bSMartin Habets static int efx_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **xdpfs, 6556e173d3bSMartin Habets u32 flags) 6566e173d3bSMartin Habets { 6576e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(dev); 6586e173d3bSMartin Habets 6596e173d3bSMartin Habets if (!netif_running(dev)) 6606e173d3bSMartin Habets return -EINVAL; 6616e173d3bSMartin Habets 66271ad88f6SMartin Habets return efx_siena_xdp_tx_buffers(efx, n, xdpfs, flags & XDP_XMIT_FLUSH); 6636e173d3bSMartin Habets } 6646e173d3bSMartin Habets 6656e173d3bSMartin Habets static void efx_update_name(struct efx_nic *efx) 6666e173d3bSMartin Habets { 6676e173d3bSMartin Habets strcpy(efx->name, efx->net_dev->name); 66871ad88f6SMartin Habets efx_siena_mtd_rename(efx); 66971ad88f6SMartin Habets efx_siena_set_channel_names(efx); 6706e173d3bSMartin Habets } 6716e173d3bSMartin Habets 6726e173d3bSMartin Habets static int efx_netdev_event(struct notifier_block *this, 6736e173d3bSMartin Habets unsigned long event, void *ptr) 6746e173d3bSMartin Habets { 6756e173d3bSMartin Habets struct net_device *net_dev = netdev_notifier_info_to_dev(ptr); 6766e173d3bSMartin Habets 6776e173d3bSMartin Habets if ((net_dev->netdev_ops == &efx_netdev_ops) && 6786e173d3bSMartin Habets event == NETDEV_CHANGENAME) 6796e173d3bSMartin Habets efx_update_name(netdev_priv(net_dev)); 6806e173d3bSMartin Habets 6816e173d3bSMartin Habets return NOTIFY_DONE; 6826e173d3bSMartin Habets } 6836e173d3bSMartin Habets 6846e173d3bSMartin Habets static struct notifier_block efx_netdev_notifier = { 6856e173d3bSMartin Habets .notifier_call = efx_netdev_event, 6866e173d3bSMartin Habets }; 6876e173d3bSMartin Habets 6886e173d3bSMartin Habets static ssize_t phy_type_show(struct device *dev, 6896e173d3bSMartin Habets struct device_attribute *attr, char *buf) 6906e173d3bSMartin Habets { 6916e173d3bSMartin Habets struct efx_nic *efx = dev_get_drvdata(dev); 6926e173d3bSMartin Habets return sprintf(buf, "%d\n", efx->phy_type); 6936e173d3bSMartin Habets } 6946e173d3bSMartin Habets static DEVICE_ATTR_RO(phy_type); 6956e173d3bSMartin Habets 6966e173d3bSMartin Habets static int efx_register_netdev(struct efx_nic *efx) 6976e173d3bSMartin Habets { 6986e173d3bSMartin Habets struct net_device *net_dev = efx->net_dev; 6996e173d3bSMartin Habets struct efx_channel *channel; 7006e173d3bSMartin Habets int rc; 7016e173d3bSMartin Habets 7026e173d3bSMartin Habets net_dev->watchdog_timeo = 5 * HZ; 7036e173d3bSMartin Habets net_dev->irq = efx->pci_dev->irq; 7046e173d3bSMartin Habets net_dev->netdev_ops = &efx_netdev_ops; 7056e173d3bSMartin Habets if (efx_nic_rev(efx) >= EFX_REV_HUNT_A0) 7066e173d3bSMartin Habets net_dev->priv_flags |= IFF_UNICAST_FLT; 70771ad88f6SMartin Habets net_dev->ethtool_ops = &efx_siena_ethtool_ops; 7086e173d3bSMartin Habets netif_set_tso_max_segs(net_dev, EFX_TSO_MAX_SEGS); 7096e173d3bSMartin Habets net_dev->min_mtu = EFX_MIN_MTU; 7106e173d3bSMartin Habets net_dev->max_mtu = EFX_MAX_MTU; 7116e173d3bSMartin Habets 7126e173d3bSMartin Habets rtnl_lock(); 7136e173d3bSMartin Habets 7146e173d3bSMartin Habets /* Enable resets to be scheduled and check whether any were 7156e173d3bSMartin Habets * already requested. If so, the NIC is probably hosed so we 7166e173d3bSMartin Habets * abort. 7176e173d3bSMartin Habets */ 7186e173d3bSMartin Habets efx->state = STATE_READY; 7196e173d3bSMartin Habets smp_mb(); /* ensure we change state before checking reset_pending */ 7206e173d3bSMartin Habets if (efx->reset_pending) { 7216e173d3bSMartin Habets pci_err(efx->pci_dev, "aborting probe due to scheduled reset\n"); 7226e173d3bSMartin Habets rc = -EIO; 7236e173d3bSMartin Habets goto fail_locked; 7246e173d3bSMartin Habets } 7256e173d3bSMartin Habets 7266e173d3bSMartin Habets rc = dev_alloc_name(net_dev, net_dev->name); 7276e173d3bSMartin Habets if (rc < 0) 7286e173d3bSMartin Habets goto fail_locked; 7296e173d3bSMartin Habets efx_update_name(efx); 7306e173d3bSMartin Habets 7316e173d3bSMartin Habets /* Always start with carrier off; PHY events will detect the link */ 7326e173d3bSMartin Habets netif_carrier_off(net_dev); 7336e173d3bSMartin Habets 7346e173d3bSMartin Habets rc = register_netdevice(net_dev); 7356e173d3bSMartin Habets if (rc) 7366e173d3bSMartin Habets goto fail_locked; 7376e173d3bSMartin Habets 7386e173d3bSMartin Habets efx_for_each_channel(channel, efx) { 7396e173d3bSMartin Habets struct efx_tx_queue *tx_queue; 7406e173d3bSMartin Habets efx_for_each_channel_tx_queue(tx_queue, channel) 74171ad88f6SMartin Habets efx_siena_init_tx_queue_core_txq(tx_queue); 7426e173d3bSMartin Habets } 7436e173d3bSMartin Habets 7446e173d3bSMartin Habets efx_associate(efx); 7456e173d3bSMartin Habets 7466e173d3bSMartin Habets rtnl_unlock(); 7476e173d3bSMartin Habets 7486e173d3bSMartin Habets rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type); 7496e173d3bSMartin Habets if (rc) { 7506e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, 7516e173d3bSMartin Habets "failed to init net dev attributes\n"); 7526e173d3bSMartin Habets goto fail_registered; 7536e173d3bSMartin Habets } 7546e173d3bSMartin Habets 75571ad88f6SMartin Habets efx_siena_init_mcdi_logging(efx); 7566e173d3bSMartin Habets 7576e173d3bSMartin Habets return 0; 7586e173d3bSMartin Habets 7596e173d3bSMartin Habets fail_registered: 7606e173d3bSMartin Habets rtnl_lock(); 7616e173d3bSMartin Habets efx_dissociate(efx); 7626e173d3bSMartin Habets unregister_netdevice(net_dev); 7636e173d3bSMartin Habets fail_locked: 7646e173d3bSMartin Habets efx->state = STATE_UNINIT; 7656e173d3bSMartin Habets rtnl_unlock(); 7666e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, "could not register net dev\n"); 7676e173d3bSMartin Habets return rc; 7686e173d3bSMartin Habets } 7696e173d3bSMartin Habets 7706e173d3bSMartin Habets static void efx_unregister_netdev(struct efx_nic *efx) 7716e173d3bSMartin Habets { 7726e173d3bSMartin Habets if (!efx->net_dev) 7736e173d3bSMartin Habets return; 7746e173d3bSMartin Habets 7756e173d3bSMartin Habets BUG_ON(netdev_priv(efx->net_dev) != efx); 7766e173d3bSMartin Habets 7776e173d3bSMartin Habets if (efx_dev_registered(efx)) { 7786e173d3bSMartin Habets strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); 77971ad88f6SMartin Habets efx_siena_fini_mcdi_logging(efx); 7806e173d3bSMartin Habets device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); 7816e173d3bSMartin Habets unregister_netdev(efx->net_dev); 7826e173d3bSMartin Habets } 7836e173d3bSMartin Habets } 7846e173d3bSMartin Habets 7856e173d3bSMartin Habets /************************************************************************** 7866e173d3bSMartin Habets * 7876e173d3bSMartin Habets * List of NICs we support 7886e173d3bSMartin Habets * 7896e173d3bSMartin Habets **************************************************************************/ 7906e173d3bSMartin Habets 7916e173d3bSMartin Habets /* PCI device ID table */ 7926e173d3bSMartin Habets static const struct pci_device_id efx_pci_table[] = { 793956f2d86SMartin Habets {PCI_DEVICE(PCI_VENDOR_ID_SOLARFLARE, 0x0803), /* SFC9020 */ 794956f2d86SMartin Habets .driver_data = (unsigned long)&siena_a0_nic_type}, 795956f2d86SMartin Habets {PCI_DEVICE(PCI_VENDOR_ID_SOLARFLARE, 0x0813), /* SFL9021 */ 796956f2d86SMartin Habets .driver_data = (unsigned long)&siena_a0_nic_type}, 7976e173d3bSMartin Habets {0} /* end of list */ 7986e173d3bSMartin Habets }; 7996e173d3bSMartin Habets 8006e173d3bSMartin Habets /************************************************************************** 8016e173d3bSMartin Habets * 8026e173d3bSMartin Habets * Data housekeeping 8036e173d3bSMartin Habets * 8046e173d3bSMartin Habets **************************************************************************/ 8056e173d3bSMartin Habets 80671ad88f6SMartin Habets void efx_siena_update_sw_stats(struct efx_nic *efx, u64 *stats) 8076e173d3bSMartin Habets { 8086e173d3bSMartin Habets u64 n_rx_nodesc_trunc = 0; 8096e173d3bSMartin Habets struct efx_channel *channel; 8106e173d3bSMartin Habets 8116e173d3bSMartin Habets efx_for_each_channel(channel, efx) 8126e173d3bSMartin Habets n_rx_nodesc_trunc += channel->n_rx_nodesc_trunc; 8136e173d3bSMartin Habets stats[GENERIC_STAT_rx_nodesc_trunc] = n_rx_nodesc_trunc; 8146e173d3bSMartin Habets stats[GENERIC_STAT_rx_noskb_drops] = atomic_read(&efx->n_rx_noskb_drops); 8156e173d3bSMartin Habets } 8166e173d3bSMartin Habets 8176e173d3bSMartin Habets /************************************************************************** 8186e173d3bSMartin Habets * 8196e173d3bSMartin Habets * PCI interface 8206e173d3bSMartin Habets * 8216e173d3bSMartin Habets **************************************************************************/ 8226e173d3bSMartin Habets 8236e173d3bSMartin Habets /* Main body of final NIC shutdown code 8246e173d3bSMartin Habets * This is called only at module unload (or hotplug removal). 8256e173d3bSMartin Habets */ 8266e173d3bSMartin Habets static void efx_pci_remove_main(struct efx_nic *efx) 8276e173d3bSMartin Habets { 8286e173d3bSMartin Habets /* Flush reset_work. It can no longer be scheduled since we 8296e173d3bSMartin Habets * are not READY. 8306e173d3bSMartin Habets */ 8316e173d3bSMartin Habets BUG_ON(efx->state == STATE_READY); 83271ad88f6SMartin Habets efx_siena_flush_reset_workqueue(efx); 8336e173d3bSMartin Habets 83471ad88f6SMartin Habets efx_siena_disable_interrupts(efx); 83571ad88f6SMartin Habets efx_siena_clear_interrupt_affinity(efx); 836c8443b69SMartin Habets efx_siena_fini_interrupt(efx); 8376e173d3bSMartin Habets efx_fini_port(efx); 8386e173d3bSMartin Habets efx->type->fini(efx); 83971ad88f6SMartin Habets efx_siena_fini_napi(efx); 8406e173d3bSMartin Habets efx_remove_all(efx); 8416e173d3bSMartin Habets } 8426e173d3bSMartin Habets 8436e173d3bSMartin Habets /* Final NIC shutdown 8446e173d3bSMartin Habets * This is called only at module unload (or hotplug removal). A PF can call 8456e173d3bSMartin Habets * this on its VFs to ensure they are unbound first. 8466e173d3bSMartin Habets */ 8476e173d3bSMartin Habets static void efx_pci_remove(struct pci_dev *pci_dev) 8486e173d3bSMartin Habets { 8496e173d3bSMartin Habets struct efx_nic *efx; 8506e173d3bSMartin Habets 8516e173d3bSMartin Habets efx = pci_get_drvdata(pci_dev); 8526e173d3bSMartin Habets if (!efx) 8536e173d3bSMartin Habets return; 8546e173d3bSMartin Habets 8556e173d3bSMartin Habets /* Mark the NIC as fini, then stop the interface */ 8566e173d3bSMartin Habets rtnl_lock(); 8576e173d3bSMartin Habets efx_dissociate(efx); 8586e173d3bSMartin Habets dev_close(efx->net_dev); 85971ad88f6SMartin Habets efx_siena_disable_interrupts(efx); 8606e173d3bSMartin Habets efx->state = STATE_UNINIT; 8616e173d3bSMartin Habets rtnl_unlock(); 8626e173d3bSMartin Habets 8636e173d3bSMartin Habets if (efx->type->sriov_fini) 8646e173d3bSMartin Habets efx->type->sriov_fini(efx); 8656e173d3bSMartin Habets 8666e173d3bSMartin Habets efx_unregister_netdev(efx); 8676e173d3bSMartin Habets 86871ad88f6SMartin Habets efx_siena_mtd_remove(efx); 8696e173d3bSMartin Habets 8706e173d3bSMartin Habets efx_pci_remove_main(efx); 8716e173d3bSMartin Habets 87271ad88f6SMartin Habets efx_siena_fini_io(efx); 8736e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n"); 8746e173d3bSMartin Habets 87571ad88f6SMartin Habets efx_siena_fini_struct(efx); 8766e173d3bSMartin Habets free_netdev(efx->net_dev); 8776e173d3bSMartin Habets 8786e173d3bSMartin Habets pci_disable_pcie_error_reporting(pci_dev); 8796e173d3bSMartin Habets }; 8806e173d3bSMartin Habets 8816e173d3bSMartin Habets /* NIC VPD information 8826e173d3bSMartin Habets * Called during probe to display the part number of the 8836e173d3bSMartin Habets * installed NIC. 8846e173d3bSMartin Habets */ 8856e173d3bSMartin Habets static void efx_probe_vpd_strings(struct efx_nic *efx) 8866e173d3bSMartin Habets { 8876e173d3bSMartin Habets struct pci_dev *dev = efx->pci_dev; 8886e173d3bSMartin Habets unsigned int vpd_size, kw_len; 8896e173d3bSMartin Habets u8 *vpd_data; 8906e173d3bSMartin Habets int start; 8916e173d3bSMartin Habets 8926e173d3bSMartin Habets vpd_data = pci_vpd_alloc(dev, &vpd_size); 8936e173d3bSMartin Habets if (IS_ERR(vpd_data)) { 8946e173d3bSMartin Habets pci_warn(dev, "Unable to read VPD\n"); 8956e173d3bSMartin Habets return; 8966e173d3bSMartin Habets } 8976e173d3bSMartin Habets 8986e173d3bSMartin Habets start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size, 8996e173d3bSMartin Habets PCI_VPD_RO_KEYWORD_PARTNO, &kw_len); 9006e173d3bSMartin Habets if (start < 0) 9016e173d3bSMartin Habets pci_err(dev, "Part number not found or incomplete\n"); 9026e173d3bSMartin Habets else 9036e173d3bSMartin Habets pci_info(dev, "Part Number : %.*s\n", kw_len, vpd_data + start); 9046e173d3bSMartin Habets 9056e173d3bSMartin Habets start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size, 9066e173d3bSMartin Habets PCI_VPD_RO_KEYWORD_SERIALNO, &kw_len); 9076e173d3bSMartin Habets if (start < 0) 9086e173d3bSMartin Habets pci_err(dev, "Serial number not found or incomplete\n"); 9096e173d3bSMartin Habets else 9106e173d3bSMartin Habets efx->vpd_sn = kmemdup_nul(vpd_data + start, kw_len, GFP_KERNEL); 9116e173d3bSMartin Habets 9126e173d3bSMartin Habets kfree(vpd_data); 9136e173d3bSMartin Habets } 9146e173d3bSMartin Habets 9156e173d3bSMartin Habets 9166e173d3bSMartin Habets /* Main body of NIC initialisation 9176e173d3bSMartin Habets * This is called at module load (or hotplug insertion, theoretically). 9186e173d3bSMartin Habets */ 9196e173d3bSMartin Habets static int efx_pci_probe_main(struct efx_nic *efx) 9206e173d3bSMartin Habets { 9216e173d3bSMartin Habets int rc; 9226e173d3bSMartin Habets 9236e173d3bSMartin Habets /* Do start-of-day initialisation */ 9246e173d3bSMartin Habets rc = efx_probe_all(efx); 9256e173d3bSMartin Habets if (rc) 9266e173d3bSMartin Habets goto fail1; 9276e173d3bSMartin Habets 92871ad88f6SMartin Habets efx_siena_init_napi(efx); 9296e173d3bSMartin Habets 9306e173d3bSMartin Habets down_write(&efx->filter_sem); 9316e173d3bSMartin Habets rc = efx->type->init(efx); 9326e173d3bSMartin Habets up_write(&efx->filter_sem); 9336e173d3bSMartin Habets if (rc) { 9346e173d3bSMartin Habets pci_err(efx->pci_dev, "failed to initialise NIC\n"); 9356e173d3bSMartin Habets goto fail3; 9366e173d3bSMartin Habets } 9376e173d3bSMartin Habets 9386e173d3bSMartin Habets rc = efx_init_port(efx); 9396e173d3bSMartin Habets if (rc) { 9406e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev, 9416e173d3bSMartin Habets "failed to initialise port\n"); 9426e173d3bSMartin Habets goto fail4; 9436e173d3bSMartin Habets } 9446e173d3bSMartin Habets 945c8443b69SMartin Habets rc = efx_siena_init_interrupt(efx); 9466e173d3bSMartin Habets if (rc) 9476e173d3bSMartin Habets goto fail5; 9486e173d3bSMartin Habets 94971ad88f6SMartin Habets efx_siena_set_interrupt_affinity(efx); 95071ad88f6SMartin Habets rc = efx_siena_enable_interrupts(efx); 9516e173d3bSMartin Habets if (rc) 9526e173d3bSMartin Habets goto fail6; 9536e173d3bSMartin Habets 9546e173d3bSMartin Habets return 0; 9556e173d3bSMartin Habets 9566e173d3bSMartin Habets fail6: 95771ad88f6SMartin Habets efx_siena_clear_interrupt_affinity(efx); 958c8443b69SMartin Habets efx_siena_fini_interrupt(efx); 9596e173d3bSMartin Habets fail5: 9606e173d3bSMartin Habets efx_fini_port(efx); 9616e173d3bSMartin Habets fail4: 9626e173d3bSMartin Habets efx->type->fini(efx); 9636e173d3bSMartin Habets fail3: 96471ad88f6SMartin Habets efx_siena_fini_napi(efx); 9656e173d3bSMartin Habets efx_remove_all(efx); 9666e173d3bSMartin Habets fail1: 9676e173d3bSMartin Habets return rc; 9686e173d3bSMartin Habets } 9696e173d3bSMartin Habets 9706e173d3bSMartin Habets static int efx_pci_probe_post_io(struct efx_nic *efx) 9716e173d3bSMartin Habets { 9726e173d3bSMartin Habets struct net_device *net_dev = efx->net_dev; 9736e173d3bSMartin Habets int rc = efx_pci_probe_main(efx); 9746e173d3bSMartin Habets 9756e173d3bSMartin Habets if (rc) 9766e173d3bSMartin Habets return rc; 9776e173d3bSMartin Habets 9786e173d3bSMartin Habets if (efx->type->sriov_init) { 9796e173d3bSMartin Habets rc = efx->type->sriov_init(efx); 9806e173d3bSMartin Habets if (rc) 9816e173d3bSMartin Habets pci_err(efx->pci_dev, "SR-IOV can't be enabled rc %d\n", 9826e173d3bSMartin Habets rc); 9836e173d3bSMartin Habets } 9846e173d3bSMartin Habets 9856e173d3bSMartin Habets /* Determine netdevice features */ 9866e173d3bSMartin Habets net_dev->features |= (efx->type->offload_features | NETIF_F_SG | 9876e173d3bSMartin Habets NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL); 9886e173d3bSMartin Habets if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) 9896e173d3bSMartin Habets net_dev->features |= NETIF_F_TSO6; 9906e173d3bSMartin Habets /* Check whether device supports TSO */ 9916e173d3bSMartin Habets if (!efx->type->tso_versions || !efx->type->tso_versions(efx)) 9926e173d3bSMartin Habets net_dev->features &= ~NETIF_F_ALL_TSO; 9936e173d3bSMartin Habets /* Mask for features that also apply to VLAN devices */ 9946e173d3bSMartin Habets net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG | 9956e173d3bSMartin Habets NETIF_F_HIGHDMA | NETIF_F_ALL_TSO | 9966e173d3bSMartin Habets NETIF_F_RXCSUM); 9976e173d3bSMartin Habets 9986e173d3bSMartin Habets net_dev->hw_features |= net_dev->features & ~efx->fixed_features; 9996e173d3bSMartin Habets 10006e173d3bSMartin Habets /* Disable receiving frames with bad FCS, by default. */ 10016e173d3bSMartin Habets net_dev->features &= ~NETIF_F_RXALL; 10026e173d3bSMartin Habets 10036e173d3bSMartin Habets /* Disable VLAN filtering by default. It may be enforced if 10046e173d3bSMartin Habets * the feature is fixed (i.e. VLAN filters are required to 10056e173d3bSMartin Habets * receive VLAN tagged packets due to vPort restrictions). 10066e173d3bSMartin Habets */ 10076e173d3bSMartin Habets net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; 10086e173d3bSMartin Habets net_dev->features |= efx->fixed_features; 10096e173d3bSMartin Habets 10106e173d3bSMartin Habets rc = efx_register_netdev(efx); 10116e173d3bSMartin Habets if (!rc) 10126e173d3bSMartin Habets return 0; 10136e173d3bSMartin Habets 10146e173d3bSMartin Habets efx_pci_remove_main(efx); 10156e173d3bSMartin Habets return rc; 10166e173d3bSMartin Habets } 10176e173d3bSMartin Habets 10186e173d3bSMartin Habets /* NIC initialisation 10196e173d3bSMartin Habets * 10206e173d3bSMartin Habets * This is called at module load (or hotplug insertion, 10216e173d3bSMartin Habets * theoretically). It sets up PCI mappings, resets the NIC, 10226e173d3bSMartin Habets * sets up and registers the network devices with the kernel and hooks 10236e173d3bSMartin Habets * the interrupt service routine. It does not prepare the device for 10246e173d3bSMartin Habets * transmission; this is left to the first time one of the network 10256e173d3bSMartin Habets * interfaces is brought up (i.e. efx_net_open). 10266e173d3bSMartin Habets */ 10276e173d3bSMartin Habets static int efx_pci_probe(struct pci_dev *pci_dev, 10286e173d3bSMartin Habets const struct pci_device_id *entry) 10296e173d3bSMartin Habets { 10306e173d3bSMartin Habets struct net_device *net_dev; 10316e173d3bSMartin Habets struct efx_nic *efx; 10326e173d3bSMartin Habets int rc; 10336e173d3bSMartin Habets 10346e173d3bSMartin Habets /* Allocate and initialise a struct net_device and struct efx_nic */ 10356e173d3bSMartin Habets net_dev = alloc_etherdev_mqs(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES, 10366e173d3bSMartin Habets EFX_MAX_RX_QUEUES); 10376e173d3bSMartin Habets if (!net_dev) 10386e173d3bSMartin Habets return -ENOMEM; 10396e173d3bSMartin Habets efx = netdev_priv(net_dev); 10406e173d3bSMartin Habets efx->type = (const struct efx_nic_type *) entry->driver_data; 10416e173d3bSMartin Habets efx->fixed_features |= NETIF_F_HIGHDMA; 10426e173d3bSMartin Habets 10436e173d3bSMartin Habets pci_set_drvdata(pci_dev, efx); 10446e173d3bSMartin Habets SET_NETDEV_DEV(net_dev, &pci_dev->dev); 104571ad88f6SMartin Habets rc = efx_siena_init_struct(efx, pci_dev, net_dev); 10466e173d3bSMartin Habets if (rc) 10476e173d3bSMartin Habets goto fail1; 10486e173d3bSMartin Habets 10496e173d3bSMartin Habets pci_info(pci_dev, "Solarflare NIC detected\n"); 10506e173d3bSMartin Habets 10516e173d3bSMartin Habets if (!efx->type->is_vf) 10526e173d3bSMartin Habets efx_probe_vpd_strings(efx); 10536e173d3bSMartin Habets 10546e173d3bSMartin Habets /* Set up basic I/O (BAR mappings etc) */ 105571ad88f6SMartin Habets rc = efx_siena_init_io(efx, efx->type->mem_bar(efx), 105671ad88f6SMartin Habets efx->type->max_dma_mask, 10576e173d3bSMartin Habets efx->type->mem_map_size(efx)); 10586e173d3bSMartin Habets if (rc) 10596e173d3bSMartin Habets goto fail2; 10606e173d3bSMartin Habets 10616e173d3bSMartin Habets rc = efx_pci_probe_post_io(efx); 10626e173d3bSMartin Habets if (rc) { 10636e173d3bSMartin Habets /* On failure, retry once immediately. 10646e173d3bSMartin Habets * If we aborted probe due to a scheduled reset, dismiss it. 10656e173d3bSMartin Habets */ 10666e173d3bSMartin Habets efx->reset_pending = 0; 10676e173d3bSMartin Habets rc = efx_pci_probe_post_io(efx); 10686e173d3bSMartin Habets if (rc) { 10696e173d3bSMartin Habets /* On another failure, retry once more 10706e173d3bSMartin Habets * after a 50-305ms delay. 10716e173d3bSMartin Habets */ 10726e173d3bSMartin Habets unsigned char r; 10736e173d3bSMartin Habets 10746e173d3bSMartin Habets get_random_bytes(&r, 1); 10756e173d3bSMartin Habets msleep((unsigned int)r + 50); 10766e173d3bSMartin Habets efx->reset_pending = 0; 10776e173d3bSMartin Habets rc = efx_pci_probe_post_io(efx); 10786e173d3bSMartin Habets } 10796e173d3bSMartin Habets } 10806e173d3bSMartin Habets if (rc) 10816e173d3bSMartin Habets goto fail3; 10826e173d3bSMartin Habets 10836e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n"); 10846e173d3bSMartin Habets 10856e173d3bSMartin Habets /* Try to create MTDs, but allow this to fail */ 10866e173d3bSMartin Habets rtnl_lock(); 10876e173d3bSMartin Habets rc = efx_mtd_probe(efx); 10886e173d3bSMartin Habets rtnl_unlock(); 10896e173d3bSMartin Habets if (rc && rc != -EPERM) 10906e173d3bSMartin Habets netif_warn(efx, probe, efx->net_dev, 10916e173d3bSMartin Habets "failed to create MTDs (%d)\n", rc); 10926e173d3bSMartin Habets 10936e173d3bSMartin Habets (void)pci_enable_pcie_error_reporting(pci_dev); 10946e173d3bSMartin Habets 10956e173d3bSMartin Habets if (efx->type->udp_tnl_push_ports) 10966e173d3bSMartin Habets efx->type->udp_tnl_push_ports(efx); 10976e173d3bSMartin Habets 10986e173d3bSMartin Habets return 0; 10996e173d3bSMartin Habets 11006e173d3bSMartin Habets fail3: 110171ad88f6SMartin Habets efx_siena_fini_io(efx); 11026e173d3bSMartin Habets fail2: 110371ad88f6SMartin Habets efx_siena_fini_struct(efx); 11046e173d3bSMartin Habets fail1: 11056e173d3bSMartin Habets WARN_ON(rc > 0); 11066e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc); 11076e173d3bSMartin Habets free_netdev(net_dev); 11086e173d3bSMartin Habets return rc; 11096e173d3bSMartin Habets } 11106e173d3bSMartin Habets 11116e173d3bSMartin Habets /* efx_pci_sriov_configure returns the actual number of Virtual Functions 11126e173d3bSMartin Habets * enabled on success 11136e173d3bSMartin Habets */ 1114dfb1cfbdSMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 11156e173d3bSMartin Habets static int efx_pci_sriov_configure(struct pci_dev *dev, int num_vfs) 11166e173d3bSMartin Habets { 11176e173d3bSMartin Habets int rc; 11186e173d3bSMartin Habets struct efx_nic *efx = pci_get_drvdata(dev); 11196e173d3bSMartin Habets 11206e173d3bSMartin Habets if (efx->type->sriov_configure) { 11216e173d3bSMartin Habets rc = efx->type->sriov_configure(efx, num_vfs); 11226e173d3bSMartin Habets if (rc) 11236e173d3bSMartin Habets return rc; 11246e173d3bSMartin Habets else 11256e173d3bSMartin Habets return num_vfs; 11266e173d3bSMartin Habets } else 11276e173d3bSMartin Habets return -EOPNOTSUPP; 11286e173d3bSMartin Habets } 11296e173d3bSMartin Habets #endif 11306e173d3bSMartin Habets 11316e173d3bSMartin Habets static int efx_pm_freeze(struct device *dev) 11326e173d3bSMartin Habets { 11336e173d3bSMartin Habets struct efx_nic *efx = dev_get_drvdata(dev); 11346e173d3bSMartin Habets 11356e173d3bSMartin Habets rtnl_lock(); 11366e173d3bSMartin Habets 11376e173d3bSMartin Habets if (efx->state != STATE_DISABLED) { 11386e173d3bSMartin Habets efx->state = STATE_UNINIT; 11396e173d3bSMartin Habets 11406e173d3bSMartin Habets efx_device_detach_sync(efx); 11416e173d3bSMartin Habets 114271ad88f6SMartin Habets efx_siena_stop_all(efx); 114371ad88f6SMartin Habets efx_siena_disable_interrupts(efx); 11446e173d3bSMartin Habets } 11456e173d3bSMartin Habets 11466e173d3bSMartin Habets rtnl_unlock(); 11476e173d3bSMartin Habets 11486e173d3bSMartin Habets return 0; 11496e173d3bSMartin Habets } 11506e173d3bSMartin Habets 11516e173d3bSMartin Habets static int efx_pm_thaw(struct device *dev) 11526e173d3bSMartin Habets { 11536e173d3bSMartin Habets int rc; 11546e173d3bSMartin Habets struct efx_nic *efx = dev_get_drvdata(dev); 11556e173d3bSMartin Habets 11566e173d3bSMartin Habets rtnl_lock(); 11576e173d3bSMartin Habets 11586e173d3bSMartin Habets if (efx->state != STATE_DISABLED) { 115971ad88f6SMartin Habets rc = efx_siena_enable_interrupts(efx); 11606e173d3bSMartin Habets if (rc) 11616e173d3bSMartin Habets goto fail; 11626e173d3bSMartin Habets 11636e173d3bSMartin Habets mutex_lock(&efx->mac_lock); 11644d49e5cdSMartin Habets efx_siena_mcdi_port_reconfigure(efx); 11656e173d3bSMartin Habets mutex_unlock(&efx->mac_lock); 11666e173d3bSMartin Habets 116771ad88f6SMartin Habets efx_siena_start_all(efx); 11686e173d3bSMartin Habets 11696e173d3bSMartin Habets efx_device_attach_if_not_resetting(efx); 11706e173d3bSMartin Habets 11716e173d3bSMartin Habets efx->state = STATE_READY; 11726e173d3bSMartin Habets 11736e173d3bSMartin Habets efx->type->resume_wol(efx); 11746e173d3bSMartin Habets } 11756e173d3bSMartin Habets 11766e173d3bSMartin Habets rtnl_unlock(); 11776e173d3bSMartin Habets 11786e173d3bSMartin Habets /* Reschedule any quenched resets scheduled during efx_pm_freeze() */ 117971ad88f6SMartin Habets efx_siena_queue_reset_work(efx); 11806e173d3bSMartin Habets 11816e173d3bSMartin Habets return 0; 11826e173d3bSMartin Habets 11836e173d3bSMartin Habets fail: 11846e173d3bSMartin Habets rtnl_unlock(); 11856e173d3bSMartin Habets 11866e173d3bSMartin Habets return rc; 11876e173d3bSMartin Habets } 11886e173d3bSMartin Habets 11896e173d3bSMartin Habets static int efx_pm_poweroff(struct device *dev) 11906e173d3bSMartin Habets { 11916e173d3bSMartin Habets struct pci_dev *pci_dev = to_pci_dev(dev); 11926e173d3bSMartin Habets struct efx_nic *efx = pci_get_drvdata(pci_dev); 11936e173d3bSMartin Habets 11946e173d3bSMartin Habets efx->type->fini(efx); 11956e173d3bSMartin Habets 11966e173d3bSMartin Habets efx->reset_pending = 0; 11976e173d3bSMartin Habets 11986e173d3bSMartin Habets pci_save_state(pci_dev); 11996e173d3bSMartin Habets return pci_set_power_state(pci_dev, PCI_D3hot); 12006e173d3bSMartin Habets } 12016e173d3bSMartin Habets 12026e173d3bSMartin Habets /* Used for both resume and restore */ 12036e173d3bSMartin Habets static int efx_pm_resume(struct device *dev) 12046e173d3bSMartin Habets { 12056e173d3bSMartin Habets struct pci_dev *pci_dev = to_pci_dev(dev); 12066e173d3bSMartin Habets struct efx_nic *efx = pci_get_drvdata(pci_dev); 12076e173d3bSMartin Habets int rc; 12086e173d3bSMartin Habets 12096e173d3bSMartin Habets rc = pci_set_power_state(pci_dev, PCI_D0); 12106e173d3bSMartin Habets if (rc) 12116e173d3bSMartin Habets return rc; 12126e173d3bSMartin Habets pci_restore_state(pci_dev); 12136e173d3bSMartin Habets rc = pci_enable_device(pci_dev); 12146e173d3bSMartin Habets if (rc) 12156e173d3bSMartin Habets return rc; 12166e173d3bSMartin Habets pci_set_master(efx->pci_dev); 12176e173d3bSMartin Habets rc = efx->type->reset(efx, RESET_TYPE_ALL); 12186e173d3bSMartin Habets if (rc) 12196e173d3bSMartin Habets return rc; 12206e173d3bSMartin Habets down_write(&efx->filter_sem); 12216e173d3bSMartin Habets rc = efx->type->init(efx); 12226e173d3bSMartin Habets up_write(&efx->filter_sem); 12236e173d3bSMartin Habets if (rc) 12246e173d3bSMartin Habets return rc; 12256e173d3bSMartin Habets rc = efx_pm_thaw(dev); 12266e173d3bSMartin Habets return rc; 12276e173d3bSMartin Habets } 12286e173d3bSMartin Habets 12296e173d3bSMartin Habets static int efx_pm_suspend(struct device *dev) 12306e173d3bSMartin Habets { 12316e173d3bSMartin Habets int rc; 12326e173d3bSMartin Habets 12336e173d3bSMartin Habets efx_pm_freeze(dev); 12346e173d3bSMartin Habets rc = efx_pm_poweroff(dev); 12356e173d3bSMartin Habets if (rc) 12366e173d3bSMartin Habets efx_pm_resume(dev); 12376e173d3bSMartin Habets return rc; 12386e173d3bSMartin Habets } 12396e173d3bSMartin Habets 12406e173d3bSMartin Habets static const struct dev_pm_ops efx_pm_ops = { 12416e173d3bSMartin Habets .suspend = efx_pm_suspend, 12426e173d3bSMartin Habets .resume = efx_pm_resume, 12436e173d3bSMartin Habets .freeze = efx_pm_freeze, 12446e173d3bSMartin Habets .thaw = efx_pm_thaw, 12456e173d3bSMartin Habets .poweroff = efx_pm_poweroff, 12466e173d3bSMartin Habets .restore = efx_pm_resume, 12476e173d3bSMartin Habets }; 12486e173d3bSMartin Habets 12496e173d3bSMartin Habets static struct pci_driver efx_pci_driver = { 12506e173d3bSMartin Habets .name = KBUILD_MODNAME, 12516e173d3bSMartin Habets .id_table = efx_pci_table, 12526e173d3bSMartin Habets .probe = efx_pci_probe, 12536e173d3bSMartin Habets .remove = efx_pci_remove, 12546e173d3bSMartin Habets .driver.pm = &efx_pm_ops, 125571ad88f6SMartin Habets .err_handler = &efx_siena_err_handlers, 1256dfb1cfbdSMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 12576e173d3bSMartin Habets .sriov_configure = efx_pci_sriov_configure, 12586e173d3bSMartin Habets #endif 12596e173d3bSMartin Habets }; 12606e173d3bSMartin Habets 12616e173d3bSMartin Habets /************************************************************************** 12626e173d3bSMartin Habets * 12636e173d3bSMartin Habets * Kernel module interface 12646e173d3bSMartin Habets * 12656e173d3bSMartin Habets *************************************************************************/ 12666e173d3bSMartin Habets 12676e173d3bSMartin Habets static int __init efx_init_module(void) 12686e173d3bSMartin Habets { 12696e173d3bSMartin Habets int rc; 12706e173d3bSMartin Habets 1271c5a13c31SMartin Habets pr_info("Solarflare Siena driver\n"); 12726e173d3bSMartin Habets 12736e173d3bSMartin Habets rc = register_netdevice_notifier(&efx_netdev_notifier); 12746e173d3bSMartin Habets if (rc) 12756e173d3bSMartin Habets goto err_notifier; 12766e173d3bSMartin Habets 1277*c3743039SMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 1278*c3743039SMartin Habets rc = efx_init_sriov(); 1279*c3743039SMartin Habets if (rc) 1280*c3743039SMartin Habets goto err_sriov; 1281*c3743039SMartin Habets #endif 1282*c3743039SMartin Habets 128371ad88f6SMartin Habets rc = efx_siena_create_reset_workqueue(); 12846e173d3bSMartin Habets if (rc) 12856e173d3bSMartin Habets goto err_reset; 12866e173d3bSMartin Habets 12876e173d3bSMartin Habets rc = pci_register_driver(&efx_pci_driver); 12886e173d3bSMartin Habets if (rc < 0) 12896e173d3bSMartin Habets goto err_pci; 12906e173d3bSMartin Habets 12916e173d3bSMartin Habets return 0; 12926e173d3bSMartin Habets 12936e173d3bSMartin Habets err_pci: 129471ad88f6SMartin Habets efx_siena_destroy_reset_workqueue(); 12956e173d3bSMartin Habets err_reset: 1296*c3743039SMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 1297*c3743039SMartin Habets efx_fini_sriov(); 1298*c3743039SMartin Habets err_sriov: 1299*c3743039SMartin Habets #endif 13006e173d3bSMartin Habets unregister_netdevice_notifier(&efx_netdev_notifier); 13016e173d3bSMartin Habets err_notifier: 13026e173d3bSMartin Habets return rc; 13036e173d3bSMartin Habets } 13046e173d3bSMartin Habets 13056e173d3bSMartin Habets static void __exit efx_exit_module(void) 13066e173d3bSMartin Habets { 1307c5a13c31SMartin Habets pr_info("Solarflare Siena driver unloading\n"); 13086e173d3bSMartin Habets 13096e173d3bSMartin Habets pci_unregister_driver(&efx_pci_driver); 131071ad88f6SMartin Habets efx_siena_destroy_reset_workqueue(); 1311*c3743039SMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV 1312*c3743039SMartin Habets efx_fini_sriov(); 1313*c3743039SMartin Habets #endif 13146e173d3bSMartin Habets unregister_netdevice_notifier(&efx_netdev_notifier); 13156e173d3bSMartin Habets 13166e173d3bSMartin Habets } 13176e173d3bSMartin Habets 13186e173d3bSMartin Habets module_init(efx_init_module); 13196e173d3bSMartin Habets module_exit(efx_exit_module); 13206e173d3bSMartin Habets 13216e173d3bSMartin Habets MODULE_AUTHOR("Solarflare Communications and " 13226e173d3bSMartin Habets "Michael Brown <mbrown@fensystems.co.uk>"); 1323c5a13c31SMartin Habets MODULE_DESCRIPTION("Solarflare Siena network driver"); 13246e173d3bSMartin Habets MODULE_LICENSE("GPL"); 13256e173d3bSMartin Habets MODULE_DEVICE_TABLE(pci, efx_pci_table); 1326