16e173d3bSMartin Habets // SPDX-License-Identifier: GPL-2.0-only
26e173d3bSMartin Habets /****************************************************************************
36e173d3bSMartin Habets * Driver for Solarflare network controllers and boards
46e173d3bSMartin Habets * Copyright 2018 Solarflare Communications Inc.
56e173d3bSMartin Habets *
66e173d3bSMartin Habets * This program is free software; you can redistribute it and/or modify it
76e173d3bSMartin Habets * under the terms of the GNU General Public License version 2 as published
86e173d3bSMartin Habets * by the Free Software Foundation, incorporated herein by reference.
96e173d3bSMartin Habets */
106e173d3bSMartin Habets
116e173d3bSMartin Habets #include "net_driver.h"
126e173d3bSMartin Habets #include <linux/filter.h>
136e173d3bSMartin Habets #include <linux/module.h>
146e173d3bSMartin Habets #include <linux/netdevice.h>
156e173d3bSMartin Habets #include <net/gre.h>
166e173d3bSMartin Habets #include "efx_common.h"
176e173d3bSMartin Habets #include "efx_channels.h"
186e173d3bSMartin Habets #include "efx.h"
196e173d3bSMartin Habets #include "mcdi.h"
206e173d3bSMartin Habets #include "selftest.h"
216e173d3bSMartin Habets #include "rx_common.h"
226e173d3bSMartin Habets #include "tx_common.h"
236e173d3bSMartin Habets #include "nic.h"
246e173d3bSMartin Habets #include "mcdi_port_common.h"
256e173d3bSMartin Habets #include "io.h"
266e173d3bSMartin Habets #include "mcdi_pcol.h"
276e173d3bSMartin Habets
286e173d3bSMartin Habets static unsigned int debug = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
296e173d3bSMartin Habets NETIF_MSG_LINK | NETIF_MSG_IFDOWN |
306e173d3bSMartin Habets NETIF_MSG_IFUP | NETIF_MSG_RX_ERR |
316e173d3bSMartin Habets NETIF_MSG_TX_ERR | NETIF_MSG_HW);
326e173d3bSMartin Habets module_param(debug, uint, 0);
336e173d3bSMartin Habets MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
346e173d3bSMartin Habets
356e173d3bSMartin Habets /* This is the time (in jiffies) between invocations of the hardware
366e173d3bSMartin Habets * monitor.
376e173d3bSMartin Habets * On Falcon-based NICs, this will:
386e173d3bSMartin Habets * - Check the on-board hardware monitor;
396e173d3bSMartin Habets * - Poll the link state and reconfigure the hardware as necessary.
406e173d3bSMartin Habets * On Siena-based NICs for power systems with EEH support, this will give EEH a
416e173d3bSMartin Habets * chance to start.
426e173d3bSMartin Habets */
436e173d3bSMartin Habets static unsigned int efx_monitor_interval = 1 * HZ;
446e173d3bSMartin Habets
456e173d3bSMartin Habets /* How often and how many times to poll for a reset while waiting for a
466e173d3bSMartin Habets * BIST that another function started to complete.
476e173d3bSMartin Habets */
486e173d3bSMartin Habets #define BIST_WAIT_DELAY_MS 100
496e173d3bSMartin Habets #define BIST_WAIT_DELAY_COUNT 100
506e173d3bSMartin Habets
516e173d3bSMartin Habets /* Default stats update time */
526e173d3bSMartin Habets #define STATS_PERIOD_MS_DEFAULT 1000
536e173d3bSMartin Habets
546e173d3bSMartin Habets static const unsigned int efx_reset_type_max = RESET_TYPE_MAX;
556e173d3bSMartin Habets static const char *const efx_reset_type_names[] = {
566e173d3bSMartin Habets [RESET_TYPE_INVISIBLE] = "INVISIBLE",
576e173d3bSMartin Habets [RESET_TYPE_ALL] = "ALL",
586e173d3bSMartin Habets [RESET_TYPE_RECOVER_OR_ALL] = "RECOVER_OR_ALL",
596e173d3bSMartin Habets [RESET_TYPE_WORLD] = "WORLD",
606e173d3bSMartin Habets [RESET_TYPE_RECOVER_OR_DISABLE] = "RECOVER_OR_DISABLE",
616e173d3bSMartin Habets [RESET_TYPE_DATAPATH] = "DATAPATH",
626e173d3bSMartin Habets [RESET_TYPE_MC_BIST] = "MC_BIST",
636e173d3bSMartin Habets [RESET_TYPE_DISABLE] = "DISABLE",
646e173d3bSMartin Habets [RESET_TYPE_TX_WATCHDOG] = "TX_WATCHDOG",
656e173d3bSMartin Habets [RESET_TYPE_INT_ERROR] = "INT_ERROR",
666e173d3bSMartin Habets [RESET_TYPE_DMA_ERROR] = "DMA_ERROR",
676e173d3bSMartin Habets [RESET_TYPE_TX_SKIP] = "TX_SKIP",
686e173d3bSMartin Habets [RESET_TYPE_MC_FAILURE] = "MC_FAILURE",
696e173d3bSMartin Habets [RESET_TYPE_MCDI_TIMEOUT] = "MCDI_TIMEOUT (FLR)",
706e173d3bSMartin Habets };
716e173d3bSMartin Habets
726e173d3bSMartin Habets #define RESET_TYPE(type) \
736e173d3bSMartin Habets STRING_TABLE_LOOKUP(type, efx_reset_type)
746e173d3bSMartin Habets
756e173d3bSMartin Habets /* Loopback mode names (see LOOPBACK_MODE()) */
7695e96f77SMartin Habets const unsigned int efx_siena_loopback_mode_max = LOOPBACK_MAX;
7795e96f77SMartin Habets const char *const efx_siena_loopback_mode_names[] = {
786e173d3bSMartin Habets [LOOPBACK_NONE] = "NONE",
796e173d3bSMartin Habets [LOOPBACK_DATA] = "DATAPATH",
806e173d3bSMartin Habets [LOOPBACK_GMAC] = "GMAC",
816e173d3bSMartin Habets [LOOPBACK_XGMII] = "XGMII",
826e173d3bSMartin Habets [LOOPBACK_XGXS] = "XGXS",
836e173d3bSMartin Habets [LOOPBACK_XAUI] = "XAUI",
846e173d3bSMartin Habets [LOOPBACK_GMII] = "GMII",
856e173d3bSMartin Habets [LOOPBACK_SGMII] = "SGMII",
866e173d3bSMartin Habets [LOOPBACK_XGBR] = "XGBR",
876e173d3bSMartin Habets [LOOPBACK_XFI] = "XFI",
886e173d3bSMartin Habets [LOOPBACK_XAUI_FAR] = "XAUI_FAR",
896e173d3bSMartin Habets [LOOPBACK_GMII_FAR] = "GMII_FAR",
906e173d3bSMartin Habets [LOOPBACK_SGMII_FAR] = "SGMII_FAR",
916e173d3bSMartin Habets [LOOPBACK_XFI_FAR] = "XFI_FAR",
926e173d3bSMartin Habets [LOOPBACK_GPHY] = "GPHY",
936e173d3bSMartin Habets [LOOPBACK_PHYXS] = "PHYXS",
946e173d3bSMartin Habets [LOOPBACK_PCS] = "PCS",
956e173d3bSMartin Habets [LOOPBACK_PMAPMD] = "PMA/PMD",
966e173d3bSMartin Habets [LOOPBACK_XPORT] = "XPORT",
976e173d3bSMartin Habets [LOOPBACK_XGMII_WS] = "XGMII_WS",
986e173d3bSMartin Habets [LOOPBACK_XAUI_WS] = "XAUI_WS",
996e173d3bSMartin Habets [LOOPBACK_XAUI_WS_FAR] = "XAUI_WS_FAR",
1006e173d3bSMartin Habets [LOOPBACK_XAUI_WS_NEAR] = "XAUI_WS_NEAR",
1016e173d3bSMartin Habets [LOOPBACK_GMII_WS] = "GMII_WS",
1026e173d3bSMartin Habets [LOOPBACK_XFI_WS] = "XFI_WS",
1036e173d3bSMartin Habets [LOOPBACK_XFI_WS_FAR] = "XFI_WS_FAR",
1046e173d3bSMartin Habets [LOOPBACK_PHYXS_WS] = "PHYXS_WS",
1056e173d3bSMartin Habets };
1066e173d3bSMartin Habets
1076e173d3bSMartin Habets /* Reset workqueue. If any NIC has a hardware failure then a reset will be
1086e173d3bSMartin Habets * queued onto this work queue. This is not a per-nic work queue, because
1096e173d3bSMartin Habets * efx_reset_work() acquires the rtnl lock, so resets are naturally serialised.
1106e173d3bSMartin Habets */
1116e173d3bSMartin Habets static struct workqueue_struct *reset_workqueue;
1126e173d3bSMartin Habets
efx_siena_create_reset_workqueue(void)11371ad88f6SMartin Habets int efx_siena_create_reset_workqueue(void)
1146e173d3bSMartin Habets {
115ef9b5770SMartin Habets reset_workqueue = create_singlethread_workqueue("sfc_siena_reset");
1166e173d3bSMartin Habets if (!reset_workqueue) {
1176e173d3bSMartin Habets printk(KERN_ERR "Failed to create reset workqueue\n");
1186e173d3bSMartin Habets return -ENOMEM;
1196e173d3bSMartin Habets }
1206e173d3bSMartin Habets
1216e173d3bSMartin Habets return 0;
1226e173d3bSMartin Habets }
1236e173d3bSMartin Habets
efx_siena_queue_reset_work(struct efx_nic * efx)12471ad88f6SMartin Habets void efx_siena_queue_reset_work(struct efx_nic *efx)
1256e173d3bSMartin Habets {
1266e173d3bSMartin Habets queue_work(reset_workqueue, &efx->reset_work);
1276e173d3bSMartin Habets }
1286e173d3bSMartin Habets
efx_siena_flush_reset_workqueue(struct efx_nic * efx)12971ad88f6SMartin Habets void efx_siena_flush_reset_workqueue(struct efx_nic *efx)
1306e173d3bSMartin Habets {
1316e173d3bSMartin Habets cancel_work_sync(&efx->reset_work);
1326e173d3bSMartin Habets }
1336e173d3bSMartin Habets
efx_siena_destroy_reset_workqueue(void)13471ad88f6SMartin Habets void efx_siena_destroy_reset_workqueue(void)
1356e173d3bSMartin Habets {
1366e173d3bSMartin Habets if (reset_workqueue) {
1376e173d3bSMartin Habets destroy_workqueue(reset_workqueue);
1386e173d3bSMartin Habets reset_workqueue = NULL;
1396e173d3bSMartin Habets }
1406e173d3bSMartin Habets }
1416e173d3bSMartin Habets
1426e173d3bSMartin Habets /* We assume that efx->type->reconfigure_mac will always try to sync RX
1436e173d3bSMartin Habets * filters and therefore needs to read-lock the filter table against freeing
1446e173d3bSMartin Habets */
efx_siena_mac_reconfigure(struct efx_nic * efx,bool mtu_only)14571ad88f6SMartin Habets void efx_siena_mac_reconfigure(struct efx_nic *efx, bool mtu_only)
1466e173d3bSMartin Habets {
1476e173d3bSMartin Habets if (efx->type->reconfigure_mac) {
1486e173d3bSMartin Habets down_read(&efx->filter_sem);
1496e173d3bSMartin Habets efx->type->reconfigure_mac(efx, mtu_only);
1506e173d3bSMartin Habets up_read(&efx->filter_sem);
1516e173d3bSMartin Habets }
1526e173d3bSMartin Habets }
1536e173d3bSMartin Habets
1546e173d3bSMartin Habets /* Asynchronous work item for changing MAC promiscuity and multicast
1556e173d3bSMartin Habets * hash. Avoid a drain/rx_ingress enable by reconfiguring the current
1566e173d3bSMartin Habets * MAC directly.
1576e173d3bSMartin Habets */
efx_mac_work(struct work_struct * data)1586e173d3bSMartin Habets static void efx_mac_work(struct work_struct *data)
1596e173d3bSMartin Habets {
1606e173d3bSMartin Habets struct efx_nic *efx = container_of(data, struct efx_nic, mac_work);
1616e173d3bSMartin Habets
1626e173d3bSMartin Habets mutex_lock(&efx->mac_lock);
1636e173d3bSMartin Habets if (efx->port_enabled)
16471ad88f6SMartin Habets efx_siena_mac_reconfigure(efx, false);
1656e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
1666e173d3bSMartin Habets }
1676e173d3bSMartin Habets
efx_siena_set_mac_address(struct net_device * net_dev,void * data)16871ad88f6SMartin Habets int efx_siena_set_mac_address(struct net_device *net_dev, void *data)
1696e173d3bSMartin Habets {
1706e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev);
1716e173d3bSMartin Habets struct sockaddr *addr = data;
1726e173d3bSMartin Habets u8 *new_addr = addr->sa_data;
1736e173d3bSMartin Habets u8 old_addr[6];
1746e173d3bSMartin Habets int rc;
1756e173d3bSMartin Habets
1766e173d3bSMartin Habets if (!is_valid_ether_addr(new_addr)) {
1776e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev,
1786e173d3bSMartin Habets "invalid ethernet MAC address requested: %pM\n",
1796e173d3bSMartin Habets new_addr);
1806e173d3bSMartin Habets return -EADDRNOTAVAIL;
1816e173d3bSMartin Habets }
1826e173d3bSMartin Habets
1836e173d3bSMartin Habets /* save old address */
1846e173d3bSMartin Habets ether_addr_copy(old_addr, net_dev->dev_addr);
1856e173d3bSMartin Habets eth_hw_addr_set(net_dev, new_addr);
1866e173d3bSMartin Habets if (efx->type->set_mac_address) {
1876e173d3bSMartin Habets rc = efx->type->set_mac_address(efx);
1886e173d3bSMartin Habets if (rc) {
1896e173d3bSMartin Habets eth_hw_addr_set(net_dev, old_addr);
1906e173d3bSMartin Habets return rc;
1916e173d3bSMartin Habets }
1926e173d3bSMartin Habets }
1936e173d3bSMartin Habets
1946e173d3bSMartin Habets /* Reconfigure the MAC */
1956e173d3bSMartin Habets mutex_lock(&efx->mac_lock);
19671ad88f6SMartin Habets efx_siena_mac_reconfigure(efx, false);
1976e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
1986e173d3bSMartin Habets
1996e173d3bSMartin Habets return 0;
2006e173d3bSMartin Habets }
2016e173d3bSMartin Habets
2026e173d3bSMartin Habets /* Context: netif_addr_lock held, BHs disabled. */
efx_siena_set_rx_mode(struct net_device * net_dev)20371ad88f6SMartin Habets void efx_siena_set_rx_mode(struct net_device *net_dev)
2046e173d3bSMartin Habets {
2056e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev);
2066e173d3bSMartin Habets
2076e173d3bSMartin Habets if (efx->port_enabled)
2086e173d3bSMartin Habets queue_work(efx->workqueue, &efx->mac_work);
2096e173d3bSMartin Habets /* Otherwise efx_start_port() will do this */
2106e173d3bSMartin Habets }
2116e173d3bSMartin Habets
efx_siena_set_features(struct net_device * net_dev,netdev_features_t data)21271ad88f6SMartin Habets int efx_siena_set_features(struct net_device *net_dev, netdev_features_t data)
2136e173d3bSMartin Habets {
2146e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev);
2156e173d3bSMartin Habets int rc;
2166e173d3bSMartin Habets
2176e173d3bSMartin Habets /* If disabling RX n-tuple filtering, clear existing filters */
2186e173d3bSMartin Habets if (net_dev->features & ~data & NETIF_F_NTUPLE) {
2196e173d3bSMartin Habets rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
2206e173d3bSMartin Habets if (rc)
2216e173d3bSMartin Habets return rc;
2226e173d3bSMartin Habets }
2236e173d3bSMartin Habets
2246e173d3bSMartin Habets /* If Rx VLAN filter is changed, update filters via mac_reconfigure.
2256e173d3bSMartin Habets * If rx-fcs is changed, mac_reconfigure updates that too.
2266e173d3bSMartin Habets */
2276e173d3bSMartin Habets if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
2286e173d3bSMartin Habets NETIF_F_RXFCS)) {
22971ad88f6SMartin Habets /* efx_siena_set_rx_mode() will schedule MAC work to update filters
2306e173d3bSMartin Habets * when a new features are finally set in net_dev.
2316e173d3bSMartin Habets */
23271ad88f6SMartin Habets efx_siena_set_rx_mode(net_dev);
2336e173d3bSMartin Habets }
2346e173d3bSMartin Habets
2356e173d3bSMartin Habets return 0;
2366e173d3bSMartin Habets }
2376e173d3bSMartin Habets
2386e173d3bSMartin Habets /* This ensures that the kernel is kept informed (via
2396e173d3bSMartin Habets * netif_carrier_on/off) of the link status, and also maintains the
2406e173d3bSMartin Habets * link status's stop on the port's TX queue.
2416e173d3bSMartin Habets */
efx_siena_link_status_changed(struct efx_nic * efx)24271ad88f6SMartin Habets void efx_siena_link_status_changed(struct efx_nic *efx)
2436e173d3bSMartin Habets {
2446e173d3bSMartin Habets struct efx_link_state *link_state = &efx->link_state;
2456e173d3bSMartin Habets
2466e173d3bSMartin Habets /* SFC Bug 5356: A net_dev notifier is registered, so we must ensure
2476e173d3bSMartin Habets * that no events are triggered between unregister_netdev() and the
2486e173d3bSMartin Habets * driver unloading. A more general condition is that NETDEV_CHANGE
2496e173d3bSMartin Habets * can only be generated between NETDEV_UP and NETDEV_DOWN
2506e173d3bSMartin Habets */
2516e173d3bSMartin Habets if (!netif_running(efx->net_dev))
2526e173d3bSMartin Habets return;
2536e173d3bSMartin Habets
2546e173d3bSMartin Habets if (link_state->up != netif_carrier_ok(efx->net_dev)) {
2556e173d3bSMartin Habets efx->n_link_state_changes++;
2566e173d3bSMartin Habets
2576e173d3bSMartin Habets if (link_state->up)
2586e173d3bSMartin Habets netif_carrier_on(efx->net_dev);
2596e173d3bSMartin Habets else
2606e173d3bSMartin Habets netif_carrier_off(efx->net_dev);
2616e173d3bSMartin Habets }
2626e173d3bSMartin Habets
2636e173d3bSMartin Habets /* Status message for kernel log */
2646e173d3bSMartin Habets if (link_state->up)
2656e173d3bSMartin Habets netif_info(efx, link, efx->net_dev,
2666e173d3bSMartin Habets "link up at %uMbps %s-duplex (MTU %d)\n",
2676e173d3bSMartin Habets link_state->speed, link_state->fd ? "full" : "half",
2686e173d3bSMartin Habets efx->net_dev->mtu);
2696e173d3bSMartin Habets else
2706e173d3bSMartin Habets netif_info(efx, link, efx->net_dev, "link down\n");
2716e173d3bSMartin Habets }
2726e173d3bSMartin Habets
efx_siena_xdp_max_mtu(struct efx_nic * efx)27371ad88f6SMartin Habets unsigned int efx_siena_xdp_max_mtu(struct efx_nic *efx)
2746e173d3bSMartin Habets {
2756e173d3bSMartin Habets /* The maximum MTU that we can fit in a single page, allowing for
2766e173d3bSMartin Habets * framing, overhead and XDP headroom + tailroom.
2776e173d3bSMartin Habets */
2786e173d3bSMartin Habets int overhead = EFX_MAX_FRAME_LEN(0) + sizeof(struct efx_rx_page_state) +
2796e173d3bSMartin Habets efx->rx_prefix_size + efx->type->rx_buffer_padding +
2806e173d3bSMartin Habets efx->rx_ip_align + EFX_XDP_HEADROOM + EFX_XDP_TAILROOM;
2816e173d3bSMartin Habets
2826e173d3bSMartin Habets return PAGE_SIZE - overhead;
2836e173d3bSMartin Habets }
2846e173d3bSMartin Habets
2856e173d3bSMartin Habets /* Context: process, rtnl_lock() held. */
efx_siena_change_mtu(struct net_device * net_dev,int new_mtu)28671ad88f6SMartin Habets int efx_siena_change_mtu(struct net_device *net_dev, int new_mtu)
2876e173d3bSMartin Habets {
2886e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev);
2896e173d3bSMartin Habets int rc;
2906e173d3bSMartin Habets
2916e173d3bSMartin Habets rc = efx_check_disabled(efx);
2926e173d3bSMartin Habets if (rc)
2936e173d3bSMartin Habets return rc;
2946e173d3bSMartin Habets
2956e173d3bSMartin Habets if (rtnl_dereference(efx->xdp_prog) &&
29671ad88f6SMartin Habets new_mtu > efx_siena_xdp_max_mtu(efx)) {
2976e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev,
2986e173d3bSMartin Habets "Requested MTU of %d too big for XDP (max: %d)\n",
29971ad88f6SMartin Habets new_mtu, efx_siena_xdp_max_mtu(efx));
3006e173d3bSMartin Habets return -EINVAL;
3016e173d3bSMartin Habets }
3026e173d3bSMartin Habets
3036e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu);
3046e173d3bSMartin Habets
3056e173d3bSMartin Habets efx_device_detach_sync(efx);
30671ad88f6SMartin Habets efx_siena_stop_all(efx);
3076e173d3bSMartin Habets
3086e173d3bSMartin Habets mutex_lock(&efx->mac_lock);
3096e173d3bSMartin Habets net_dev->mtu = new_mtu;
31071ad88f6SMartin Habets efx_siena_mac_reconfigure(efx, true);
3116e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
3126e173d3bSMartin Habets
31371ad88f6SMartin Habets efx_siena_start_all(efx);
3146e173d3bSMartin Habets efx_device_attach_if_not_resetting(efx);
3156e173d3bSMartin Habets return 0;
3166e173d3bSMartin Habets }
3176e173d3bSMartin Habets
3186e173d3bSMartin Habets /**************************************************************************
3196e173d3bSMartin Habets *
3206e173d3bSMartin Habets * Hardware monitor
3216e173d3bSMartin Habets *
3226e173d3bSMartin Habets **************************************************************************/
3236e173d3bSMartin Habets
3246e173d3bSMartin Habets /* Run periodically off the general workqueue */
efx_monitor(struct work_struct * data)3256e173d3bSMartin Habets static void efx_monitor(struct work_struct *data)
3266e173d3bSMartin Habets {
3276e173d3bSMartin Habets struct efx_nic *efx = container_of(data, struct efx_nic,
3286e173d3bSMartin Habets monitor_work.work);
3296e173d3bSMartin Habets
3306e173d3bSMartin Habets netif_vdbg(efx, timer, efx->net_dev,
3316e173d3bSMartin Habets "hardware monitor executing on CPU %d\n",
3326e173d3bSMartin Habets raw_smp_processor_id());
3336e173d3bSMartin Habets BUG_ON(efx->type->monitor == NULL);
3346e173d3bSMartin Habets
3356e173d3bSMartin Habets /* If the mac_lock is already held then it is likely a port
3366e173d3bSMartin Habets * reconfiguration is already in place, which will likely do
3376e173d3bSMartin Habets * most of the work of monitor() anyway.
3386e173d3bSMartin Habets */
3396e173d3bSMartin Habets if (mutex_trylock(&efx->mac_lock)) {
3406e173d3bSMartin Habets if (efx->port_enabled && efx->type->monitor)
3416e173d3bSMartin Habets efx->type->monitor(efx);
3426e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
3436e173d3bSMartin Habets }
3446e173d3bSMartin Habets
34571ad88f6SMartin Habets efx_siena_start_monitor(efx);
3466e173d3bSMartin Habets }
3476e173d3bSMartin Habets
efx_siena_start_monitor(struct efx_nic * efx)34871ad88f6SMartin Habets void efx_siena_start_monitor(struct efx_nic *efx)
3496e173d3bSMartin Habets {
3506e173d3bSMartin Habets if (efx->type->monitor)
3516e173d3bSMartin Habets queue_delayed_work(efx->workqueue, &efx->monitor_work,
3526e173d3bSMartin Habets efx_monitor_interval);
3536e173d3bSMartin Habets }
3546e173d3bSMartin Habets
3556e173d3bSMartin Habets /**************************************************************************
3566e173d3bSMartin Habets *
3576e173d3bSMartin Habets * Event queue processing
3586e173d3bSMartin Habets *
3596e173d3bSMartin Habets *************************************************************************/
3606e173d3bSMartin Habets
3616e173d3bSMartin Habets /* Channels are shutdown and reinitialised whilst the NIC is running
3626e173d3bSMartin Habets * to propagate configuration changes (mtu, checksum offload), or
3636e173d3bSMartin Habets * to clear hardware error conditions
3646e173d3bSMartin Habets */
efx_start_datapath(struct efx_nic * efx)3656e173d3bSMartin Habets static void efx_start_datapath(struct efx_nic *efx)
3666e173d3bSMartin Habets {
3676e173d3bSMartin Habets netdev_features_t old_features = efx->net_dev->features;
3686e173d3bSMartin Habets bool old_rx_scatter = efx->rx_scatter;
3696e173d3bSMartin Habets size_t rx_buf_len;
3706e173d3bSMartin Habets
3716e173d3bSMartin Habets /* Calculate the rx buffer allocation parameters required to
3726e173d3bSMartin Habets * support the current MTU, including padding for header
3736e173d3bSMartin Habets * alignment and overruns.
3746e173d3bSMartin Habets */
3756e173d3bSMartin Habets efx->rx_dma_len = (efx->rx_prefix_size +
3766e173d3bSMartin Habets EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
3776e173d3bSMartin Habets efx->type->rx_buffer_padding);
3786e173d3bSMartin Habets rx_buf_len = (sizeof(struct efx_rx_page_state) + EFX_XDP_HEADROOM +
3796e173d3bSMartin Habets efx->rx_ip_align + efx->rx_dma_len + EFX_XDP_TAILROOM);
3806e173d3bSMartin Habets
3816e173d3bSMartin Habets if (rx_buf_len <= PAGE_SIZE) {
3826e173d3bSMartin Habets efx->rx_scatter = efx->type->always_rx_scatter;
3836e173d3bSMartin Habets efx->rx_buffer_order = 0;
3846e173d3bSMartin Habets } else if (efx->type->can_rx_scatter) {
3856e173d3bSMartin Habets BUILD_BUG_ON(EFX_RX_USR_BUF_SIZE % L1_CACHE_BYTES);
3866e173d3bSMartin Habets BUILD_BUG_ON(sizeof(struct efx_rx_page_state) +
3876e173d3bSMartin Habets 2 * ALIGN(NET_IP_ALIGN + EFX_RX_USR_BUF_SIZE,
3886e173d3bSMartin Habets EFX_RX_BUF_ALIGNMENT) >
3896e173d3bSMartin Habets PAGE_SIZE);
3906e173d3bSMartin Habets efx->rx_scatter = true;
3916e173d3bSMartin Habets efx->rx_dma_len = EFX_RX_USR_BUF_SIZE;
3926e173d3bSMartin Habets efx->rx_buffer_order = 0;
3936e173d3bSMartin Habets } else {
3946e173d3bSMartin Habets efx->rx_scatter = false;
3956e173d3bSMartin Habets efx->rx_buffer_order = get_order(rx_buf_len);
3966e173d3bSMartin Habets }
3976e173d3bSMartin Habets
3987f9e4b2aSMartin Habets efx_siena_rx_config_page_split(efx);
3996e173d3bSMartin Habets if (efx->rx_buffer_order)
4006e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev,
4016e173d3bSMartin Habets "RX buf len=%u; page order=%u batch=%u\n",
4026e173d3bSMartin Habets efx->rx_dma_len, efx->rx_buffer_order,
4036e173d3bSMartin Habets efx->rx_pages_per_batch);
4046e173d3bSMartin Habets else
4056e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev,
4066e173d3bSMartin Habets "RX buf len=%u step=%u bpp=%u; page batch=%u\n",
4076e173d3bSMartin Habets efx->rx_dma_len, efx->rx_page_buf_step,
4086e173d3bSMartin Habets efx->rx_bufs_per_page, efx->rx_pages_per_batch);
4096e173d3bSMartin Habets
4106e173d3bSMartin Habets /* Restore previously fixed features in hw_features and remove
4116e173d3bSMartin Habets * features which are fixed now
4126e173d3bSMartin Habets */
4136e173d3bSMartin Habets efx->net_dev->hw_features |= efx->net_dev->features;
4146e173d3bSMartin Habets efx->net_dev->hw_features &= ~efx->fixed_features;
4156e173d3bSMartin Habets efx->net_dev->features |= efx->fixed_features;
4166e173d3bSMartin Habets if (efx->net_dev->features != old_features)
4176e173d3bSMartin Habets netdev_features_change(efx->net_dev);
4186e173d3bSMartin Habets
4196e173d3bSMartin Habets /* RX filters may also have scatter-enabled flags */
4206e173d3bSMartin Habets if ((efx->rx_scatter != old_rx_scatter) &&
4216e173d3bSMartin Habets efx->type->filter_update_rx_scatter)
4226e173d3bSMartin Habets efx->type->filter_update_rx_scatter(efx);
4236e173d3bSMartin Habets
4246e173d3bSMartin Habets /* We must keep at least one descriptor in a TX ring empty.
4256e173d3bSMartin Habets * We could avoid this when the queue size does not exactly
4266e173d3bSMartin Habets * match the hardware ring size, but it's not that important.
4276e173d3bSMartin Habets * Therefore we stop the queue when one more skb might fill
4286e173d3bSMartin Habets * the ring completely. We wake it when half way back to
4296e173d3bSMartin Habets * empty.
4306e173d3bSMartin Habets */
4317f9e4b2aSMartin Habets efx->txq_stop_thresh = efx->txq_entries - efx_siena_tx_max_skb_descs(efx);
4326e173d3bSMartin Habets efx->txq_wake_thresh = efx->txq_stop_thresh / 2;
4336e173d3bSMartin Habets
4346e173d3bSMartin Habets /* Initialise the channels */
43571ad88f6SMartin Habets efx_siena_start_channels(efx);
4366e173d3bSMartin Habets
43795e96f77SMartin Habets efx_siena_ptp_start_datapath(efx);
4386e173d3bSMartin Habets
4396e173d3bSMartin Habets if (netif_device_present(efx->net_dev))
4406e173d3bSMartin Habets netif_tx_wake_all_queues(efx->net_dev);
4416e173d3bSMartin Habets }
4426e173d3bSMartin Habets
efx_stop_datapath(struct efx_nic * efx)4436e173d3bSMartin Habets static void efx_stop_datapath(struct efx_nic *efx)
4446e173d3bSMartin Habets {
4456e173d3bSMartin Habets EFX_ASSERT_RESET_SERIALISED(efx);
4466e173d3bSMartin Habets BUG_ON(efx->port_enabled);
4476e173d3bSMartin Habets
44895e96f77SMartin Habets efx_siena_ptp_stop_datapath(efx);
4496e173d3bSMartin Habets
45071ad88f6SMartin Habets efx_siena_stop_channels(efx);
4516e173d3bSMartin Habets }
4526e173d3bSMartin Habets
4536e173d3bSMartin Habets /**************************************************************************
4546e173d3bSMartin Habets *
4556e173d3bSMartin Habets * Port handling
4566e173d3bSMartin Habets *
4576e173d3bSMartin Habets **************************************************************************/
4586e173d3bSMartin Habets
4594d49e5cdSMartin Habets /* Equivalent to efx_siena_link_set_advertising with all-zeroes, except does not
4606e173d3bSMartin Habets * force the Autoneg bit on.
4616e173d3bSMartin Habets */
efx_siena_link_clear_advertising(struct efx_nic * efx)46271ad88f6SMartin Habets void efx_siena_link_clear_advertising(struct efx_nic *efx)
4636e173d3bSMartin Habets {
4646e173d3bSMartin Habets bitmap_zero(efx->link_advertising, __ETHTOOL_LINK_MODE_MASK_NBITS);
4656e173d3bSMartin Habets efx->wanted_fc &= ~(EFX_FC_TX | EFX_FC_RX);
4666e173d3bSMartin Habets }
4676e173d3bSMartin Habets
efx_siena_link_set_wanted_fc(struct efx_nic * efx,u8 wanted_fc)46871ad88f6SMartin Habets void efx_siena_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc)
4696e173d3bSMartin Habets {
4706e173d3bSMartin Habets efx->wanted_fc = wanted_fc;
4716e173d3bSMartin Habets if (efx->link_advertising[0]) {
4726e173d3bSMartin Habets if (wanted_fc & EFX_FC_RX)
4736e173d3bSMartin Habets efx->link_advertising[0] |= (ADVERTISED_Pause |
4746e173d3bSMartin Habets ADVERTISED_Asym_Pause);
4756e173d3bSMartin Habets else
4766e173d3bSMartin Habets efx->link_advertising[0] &= ~(ADVERTISED_Pause |
4776e173d3bSMartin Habets ADVERTISED_Asym_Pause);
4786e173d3bSMartin Habets if (wanted_fc & EFX_FC_TX)
4796e173d3bSMartin Habets efx->link_advertising[0] ^= ADVERTISED_Asym_Pause;
4806e173d3bSMartin Habets }
4816e173d3bSMartin Habets }
4826e173d3bSMartin Habets
efx_start_port(struct efx_nic * efx)4836e173d3bSMartin Habets static void efx_start_port(struct efx_nic *efx)
4846e173d3bSMartin Habets {
4856e173d3bSMartin Habets netif_dbg(efx, ifup, efx->net_dev, "start port\n");
4866e173d3bSMartin Habets BUG_ON(efx->port_enabled);
4876e173d3bSMartin Habets
4886e173d3bSMartin Habets mutex_lock(&efx->mac_lock);
4896e173d3bSMartin Habets efx->port_enabled = true;
4906e173d3bSMartin Habets
4916e173d3bSMartin Habets /* Ensure MAC ingress/egress is enabled */
49271ad88f6SMartin Habets efx_siena_mac_reconfigure(efx, false);
4936e173d3bSMartin Habets
4946e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
4956e173d3bSMartin Habets }
4966e173d3bSMartin Habets
4976e173d3bSMartin Habets /* Cancel work for MAC reconfiguration, periodic hardware monitoring
4986e173d3bSMartin Habets * and the async self-test, wait for them to finish and prevent them
4996e173d3bSMartin Habets * being scheduled again. This doesn't cover online resets, which
5006e173d3bSMartin Habets * should only be cancelled when removing the device.
5016e173d3bSMartin Habets */
efx_stop_port(struct efx_nic * efx)5026e173d3bSMartin Habets static void efx_stop_port(struct efx_nic *efx)
5036e173d3bSMartin Habets {
5046e173d3bSMartin Habets netif_dbg(efx, ifdown, efx->net_dev, "stop port\n");
5056e173d3bSMartin Habets
5066e173d3bSMartin Habets EFX_ASSERT_RESET_SERIALISED(efx);
5076e173d3bSMartin Habets
5086e173d3bSMartin Habets mutex_lock(&efx->mac_lock);
5096e173d3bSMartin Habets efx->port_enabled = false;
5106e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
5116e173d3bSMartin Habets
5126e173d3bSMartin Habets /* Serialise against efx_set_multicast_list() */
5136e173d3bSMartin Habets netif_addr_lock_bh(efx->net_dev);
5146e173d3bSMartin Habets netif_addr_unlock_bh(efx->net_dev);
5156e173d3bSMartin Habets
5166e173d3bSMartin Habets cancel_delayed_work_sync(&efx->monitor_work);
51795e96f77SMartin Habets efx_siena_selftest_async_cancel(efx);
5186e173d3bSMartin Habets cancel_work_sync(&efx->mac_work);
5196e173d3bSMartin Habets }
5206e173d3bSMartin Habets
5216e173d3bSMartin Habets /* If the interface is supposed to be running but is not, start
5226e173d3bSMartin Habets * the hardware and software data path, regular activity for the port
5236e173d3bSMartin Habets * (MAC statistics, link polling, etc.) and schedule the port to be
5246e173d3bSMartin Habets * reconfigured. Interrupts must already be enabled. This function
5256e173d3bSMartin Habets * is safe to call multiple times, so long as the NIC is not disabled.
5266e173d3bSMartin Habets * Requires the RTNL lock.
5276e173d3bSMartin Habets */
efx_siena_start_all(struct efx_nic * efx)52871ad88f6SMartin Habets void efx_siena_start_all(struct efx_nic *efx)
5296e173d3bSMartin Habets {
5306e173d3bSMartin Habets EFX_ASSERT_RESET_SERIALISED(efx);
5316e173d3bSMartin Habets BUG_ON(efx->state == STATE_DISABLED);
5326e173d3bSMartin Habets
5336e173d3bSMartin Habets /* Check that it is appropriate to restart the interface. All
5346e173d3bSMartin Habets * of these flags are safe to read under just the rtnl lock
5356e173d3bSMartin Habets */
5366e173d3bSMartin Habets if (efx->port_enabled || !netif_running(efx->net_dev) ||
5376e173d3bSMartin Habets efx->reset_pending)
5386e173d3bSMartin Habets return;
5396e173d3bSMartin Habets
5406e173d3bSMartin Habets efx_start_port(efx);
5416e173d3bSMartin Habets efx_start_datapath(efx);
5426e173d3bSMartin Habets
5436e173d3bSMartin Habets /* Start the hardware monitor if there is one */
54471ad88f6SMartin Habets efx_siena_start_monitor(efx);
5456e173d3bSMartin Habets
5466e173d3bSMartin Habets /* Link state detection is normally event-driven; we have
5476e173d3bSMartin Habets * to poll now because we could have missed a change
5486e173d3bSMartin Habets */
5496e173d3bSMartin Habets mutex_lock(&efx->mac_lock);
5504d49e5cdSMartin Habets if (efx_siena_mcdi_phy_poll(efx))
55171ad88f6SMartin Habets efx_siena_link_status_changed(efx);
5526e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
5536e173d3bSMartin Habets
5546e173d3bSMartin Habets if (efx->type->start_stats) {
5556e173d3bSMartin Habets efx->type->start_stats(efx);
5566e173d3bSMartin Habets efx->type->pull_stats(efx);
5576e173d3bSMartin Habets spin_lock_bh(&efx->stats_lock);
5586e173d3bSMartin Habets efx->type->update_stats(efx, NULL, NULL);
5596e173d3bSMartin Habets spin_unlock_bh(&efx->stats_lock);
5606e173d3bSMartin Habets }
5616e173d3bSMartin Habets }
5626e173d3bSMartin Habets
5636e173d3bSMartin Habets /* Quiesce the hardware and software data path, and regular activity
5646e173d3bSMartin Habets * for the port without bringing the link down. Safe to call multiple
5656e173d3bSMartin Habets * times with the NIC in almost any state, but interrupts should be
5666e173d3bSMartin Habets * enabled. Requires the RTNL lock.
5676e173d3bSMartin Habets */
efx_siena_stop_all(struct efx_nic * efx)56871ad88f6SMartin Habets void efx_siena_stop_all(struct efx_nic *efx)
5696e173d3bSMartin Habets {
5706e173d3bSMartin Habets EFX_ASSERT_RESET_SERIALISED(efx);
5716e173d3bSMartin Habets
5726e173d3bSMartin Habets /* port_enabled can be read safely under the rtnl lock */
5736e173d3bSMartin Habets if (!efx->port_enabled)
5746e173d3bSMartin Habets return;
5756e173d3bSMartin Habets
5766e173d3bSMartin Habets if (efx->type->update_stats) {
5776e173d3bSMartin Habets /* update stats before we go down so we can accurately count
5786e173d3bSMartin Habets * rx_nodesc_drops
5796e173d3bSMartin Habets */
5806e173d3bSMartin Habets efx->type->pull_stats(efx);
5816e173d3bSMartin Habets spin_lock_bh(&efx->stats_lock);
5826e173d3bSMartin Habets efx->type->update_stats(efx, NULL, NULL);
5836e173d3bSMartin Habets spin_unlock_bh(&efx->stats_lock);
5846e173d3bSMartin Habets efx->type->stop_stats(efx);
5856e173d3bSMartin Habets }
5866e173d3bSMartin Habets
5876e173d3bSMartin Habets efx_stop_port(efx);
5886e173d3bSMartin Habets
5896e173d3bSMartin Habets /* Stop the kernel transmit interface. This is only valid if
5906e173d3bSMartin Habets * the device is stopped or detached; otherwise the watchdog
5916e173d3bSMartin Habets * may fire immediately.
5926e173d3bSMartin Habets */
5936e173d3bSMartin Habets WARN_ON(netif_running(efx->net_dev) &&
5946e173d3bSMartin Habets netif_device_present(efx->net_dev));
5956e173d3bSMartin Habets netif_tx_disable(efx->net_dev);
5966e173d3bSMartin Habets
5976e173d3bSMartin Habets efx_stop_datapath(efx);
5986e173d3bSMartin Habets }
5996e173d3bSMartin Habets
efx_siena_update_stats_atomic(struct efx_nic * efx,u64 * full_stats,struct rtnl_link_stats64 * core_stats)600c8443b69SMartin Habets static size_t efx_siena_update_stats_atomic(struct efx_nic *efx, u64 *full_stats,
601c8443b69SMartin Habets struct rtnl_link_stats64 *core_stats)
602c8443b69SMartin Habets {
603c8443b69SMartin Habets if (efx->type->update_stats_atomic)
604c8443b69SMartin Habets return efx->type->update_stats_atomic(efx, full_stats, core_stats);
605c8443b69SMartin Habets return efx->type->update_stats(efx, full_stats, core_stats);
606c8443b69SMartin Habets }
607c8443b69SMartin Habets
6086e173d3bSMartin Habets /* Context: process, dev_base_lock or RTNL held, non-blocking. */
efx_siena_net_stats(struct net_device * net_dev,struct rtnl_link_stats64 * stats)60971ad88f6SMartin Habets void efx_siena_net_stats(struct net_device *net_dev,
61071ad88f6SMartin Habets struct rtnl_link_stats64 *stats)
6116e173d3bSMartin Habets {
6126e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev);
6136e173d3bSMartin Habets
6146e173d3bSMartin Habets spin_lock_bh(&efx->stats_lock);
615c8443b69SMartin Habets efx_siena_update_stats_atomic(efx, NULL, stats);
6166e173d3bSMartin Habets spin_unlock_bh(&efx->stats_lock);
6176e173d3bSMartin Habets }
6186e173d3bSMartin Habets
6196e173d3bSMartin Habets /* Push loopback/power/transmit disable settings to the PHY, and reconfigure
6206e173d3bSMartin Habets * the MAC appropriately. All other PHY configuration changes are pushed
6216e173d3bSMartin Habets * through phy_op->set_settings(), and pushed asynchronously to the MAC
6226e173d3bSMartin Habets * through efx_monitor().
6236e173d3bSMartin Habets *
6246e173d3bSMartin Habets * Callers must hold the mac_lock
6256e173d3bSMartin Habets */
__efx_siena_reconfigure_port(struct efx_nic * efx)62671ad88f6SMartin Habets int __efx_siena_reconfigure_port(struct efx_nic *efx)
6276e173d3bSMartin Habets {
6286e173d3bSMartin Habets enum efx_phy_mode phy_mode;
6296e173d3bSMartin Habets int rc = 0;
6306e173d3bSMartin Habets
6316e173d3bSMartin Habets WARN_ON(!mutex_is_locked(&efx->mac_lock));
6326e173d3bSMartin Habets
6336e173d3bSMartin Habets /* Disable PHY transmit in mac level loopbacks */
6346e173d3bSMartin Habets phy_mode = efx->phy_mode;
6356e173d3bSMartin Habets if (LOOPBACK_INTERNAL(efx))
6366e173d3bSMartin Habets efx->phy_mode |= PHY_MODE_TX_DISABLED;
6376e173d3bSMartin Habets else
6386e173d3bSMartin Habets efx->phy_mode &= ~PHY_MODE_TX_DISABLED;
6396e173d3bSMartin Habets
6406e173d3bSMartin Habets if (efx->type->reconfigure_port)
6416e173d3bSMartin Habets rc = efx->type->reconfigure_port(efx);
6426e173d3bSMartin Habets
6436e173d3bSMartin Habets if (rc)
6446e173d3bSMartin Habets efx->phy_mode = phy_mode;
6456e173d3bSMartin Habets
6466e173d3bSMartin Habets return rc;
6476e173d3bSMartin Habets }
6486e173d3bSMartin Habets
6496e173d3bSMartin Habets /* Reinitialise the MAC to pick up new PHY settings, even if the port is
6506e173d3bSMartin Habets * disabled.
6516e173d3bSMartin Habets */
efx_siena_reconfigure_port(struct efx_nic * efx)65271ad88f6SMartin Habets int efx_siena_reconfigure_port(struct efx_nic *efx)
6536e173d3bSMartin Habets {
6546e173d3bSMartin Habets int rc;
6556e173d3bSMartin Habets
6566e173d3bSMartin Habets EFX_ASSERT_RESET_SERIALISED(efx);
6576e173d3bSMartin Habets
6586e173d3bSMartin Habets mutex_lock(&efx->mac_lock);
65971ad88f6SMartin Habets rc = __efx_siena_reconfigure_port(efx);
6606e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
6616e173d3bSMartin Habets
6626e173d3bSMartin Habets return rc;
6636e173d3bSMartin Habets }
6646e173d3bSMartin Habets
6656e173d3bSMartin Habets /**************************************************************************
6666e173d3bSMartin Habets *
6676e173d3bSMartin Habets * Device reset and suspend
6686e173d3bSMartin Habets *
6696e173d3bSMartin Habets **************************************************************************/
6706e173d3bSMartin Habets
efx_wait_for_bist_end(struct efx_nic * efx)6716e173d3bSMartin Habets static void efx_wait_for_bist_end(struct efx_nic *efx)
6726e173d3bSMartin Habets {
6736e173d3bSMartin Habets int i;
6746e173d3bSMartin Habets
6756e173d3bSMartin Habets for (i = 0; i < BIST_WAIT_DELAY_COUNT; ++i) {
6764d49e5cdSMartin Habets if (efx_siena_mcdi_poll_reboot(efx))
6776e173d3bSMartin Habets goto out;
6786e173d3bSMartin Habets msleep(BIST_WAIT_DELAY_MS);
6796e173d3bSMartin Habets }
6806e173d3bSMartin Habets
6816e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, "Warning: No MC reboot after BIST mode\n");
6826e173d3bSMartin Habets out:
6836e173d3bSMartin Habets /* Either way unset the BIST flag. If we found no reboot we probably
6846e173d3bSMartin Habets * won't recover, but we should try.
6856e173d3bSMartin Habets */
6866e173d3bSMartin Habets efx->mc_bist_for_other_fn = false;
6876e173d3bSMartin Habets }
6886e173d3bSMartin Habets
6896e173d3bSMartin Habets /* Try recovery mechanisms.
6906e173d3bSMartin Habets * For now only EEH is supported.
6916e173d3bSMartin Habets * Returns 0 if the recovery mechanisms are unsuccessful.
6926e173d3bSMartin Habets * Returns a non-zero value otherwise.
6936e173d3bSMartin Habets */
efx_siena_try_recovery(struct efx_nic * efx)69471ad88f6SMartin Habets int efx_siena_try_recovery(struct efx_nic *efx)
6956e173d3bSMartin Habets {
6966e173d3bSMartin Habets #ifdef CONFIG_EEH
6976e173d3bSMartin Habets /* A PCI error can occur and not be seen by EEH because nothing
6986e173d3bSMartin Habets * happens on the PCI bus. In this case the driver may fail and
6996e173d3bSMartin Habets * schedule a 'recover or reset', leading to this recovery handler.
7006e173d3bSMartin Habets * Manually call the eeh failure check function.
7016e173d3bSMartin Habets */
7026e173d3bSMartin Habets struct eeh_dev *eehdev = pci_dev_to_eeh_dev(efx->pci_dev);
7036e173d3bSMartin Habets if (eeh_dev_check_failure(eehdev)) {
7046e173d3bSMartin Habets /* The EEH mechanisms will handle the error and reset the
7056e173d3bSMartin Habets * device if necessary.
7066e173d3bSMartin Habets */
7076e173d3bSMartin Habets return 1;
7086e173d3bSMartin Habets }
7096e173d3bSMartin Habets #endif
7106e173d3bSMartin Habets return 0;
7116e173d3bSMartin Habets }
7126e173d3bSMartin Habets
7136e173d3bSMartin Habets /* Tears down the entire software state and most of the hardware state
7146e173d3bSMartin Habets * before reset.
7156e173d3bSMartin Habets */
efx_siena_reset_down(struct efx_nic * efx,enum reset_type method)71671ad88f6SMartin Habets void efx_siena_reset_down(struct efx_nic *efx, enum reset_type method)
7176e173d3bSMartin Habets {
7186e173d3bSMartin Habets EFX_ASSERT_RESET_SERIALISED(efx);
7196e173d3bSMartin Habets
7206e173d3bSMartin Habets if (method == RESET_TYPE_MCDI_TIMEOUT)
7216e173d3bSMartin Habets efx->type->prepare_flr(efx);
7226e173d3bSMartin Habets
72371ad88f6SMartin Habets efx_siena_stop_all(efx);
72471ad88f6SMartin Habets efx_siena_disable_interrupts(efx);
7256e173d3bSMartin Habets
7266e173d3bSMartin Habets mutex_lock(&efx->mac_lock);
7276e173d3bSMartin Habets down_write(&efx->filter_sem);
7286e173d3bSMartin Habets mutex_lock(&efx->rss_lock);
7296e173d3bSMartin Habets efx->type->fini(efx);
7306e173d3bSMartin Habets }
7316e173d3bSMartin Habets
7326e173d3bSMartin Habets /* Context: netif_tx_lock held, BHs disabled. */
efx_siena_watchdog(struct net_device * net_dev,unsigned int txqueue)73371ad88f6SMartin Habets void efx_siena_watchdog(struct net_device *net_dev, unsigned int txqueue)
7346e173d3bSMartin Habets {
7356e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev);
7366e173d3bSMartin Habets
7376e173d3bSMartin Habets netif_err(efx, tx_err, efx->net_dev,
7386e173d3bSMartin Habets "TX stuck with port_enabled=%d: resetting channels\n",
7396e173d3bSMartin Habets efx->port_enabled);
7406e173d3bSMartin Habets
74171ad88f6SMartin Habets efx_siena_schedule_reset(efx, RESET_TYPE_TX_WATCHDOG);
7426e173d3bSMartin Habets }
7436e173d3bSMartin Habets
7446e173d3bSMartin Habets /* This function will always ensure that the locks acquired in
74571ad88f6SMartin Habets * efx_siena_reset_down() are released. A failure return code indicates
7466e173d3bSMartin Habets * that we were unable to reinitialise the hardware, and the
7476e173d3bSMartin Habets * driver should be disabled. If ok is false, then the rx and tx
7486e173d3bSMartin Habets * engines are not restarted, pending a RESET_DISABLE.
7496e173d3bSMartin Habets */
efx_siena_reset_up(struct efx_nic * efx,enum reset_type method,bool ok)75071ad88f6SMartin Habets int efx_siena_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
7516e173d3bSMartin Habets {
7526e173d3bSMartin Habets int rc;
7536e173d3bSMartin Habets
7546e173d3bSMartin Habets EFX_ASSERT_RESET_SERIALISED(efx);
7556e173d3bSMartin Habets
7566e173d3bSMartin Habets if (method == RESET_TYPE_MCDI_TIMEOUT)
7576e173d3bSMartin Habets efx->type->finish_flr(efx);
7586e173d3bSMartin Habets
7596e173d3bSMartin Habets /* Ensure that SRAM is initialised even if we're disabling the device */
7606e173d3bSMartin Habets rc = efx->type->init(efx);
7616e173d3bSMartin Habets if (rc) {
7626e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, "failed to initialise NIC\n");
7636e173d3bSMartin Habets goto fail;
7646e173d3bSMartin Habets }
7656e173d3bSMartin Habets
7666e173d3bSMartin Habets if (!ok)
7676e173d3bSMartin Habets goto fail;
7686e173d3bSMartin Habets
7696e173d3bSMartin Habets if (efx->port_initialized && method != RESET_TYPE_INVISIBLE &&
7706e173d3bSMartin Habets method != RESET_TYPE_DATAPATH) {
7714d49e5cdSMartin Habets rc = efx_siena_mcdi_port_reconfigure(efx);
7726e173d3bSMartin Habets if (rc && rc != -EPERM)
7736e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev,
7746e173d3bSMartin Habets "could not restore PHY settings\n");
7756e173d3bSMartin Habets }
7766e173d3bSMartin Habets
77771ad88f6SMartin Habets rc = efx_siena_enable_interrupts(efx);
7786e173d3bSMartin Habets if (rc)
7796e173d3bSMartin Habets goto fail;
7806e173d3bSMartin Habets
781dfb1cfbdSMartin Habets #ifdef CONFIG_SFC_SIENA_SRIOV
7826e173d3bSMartin Habets rc = efx->type->vswitching_restore(efx);
7836e173d3bSMartin Habets if (rc) /* not fatal; the PF will still work fine */
7846e173d3bSMartin Habets netif_warn(efx, probe, efx->net_dev,
7856e173d3bSMartin Habets "failed to restore vswitching rc=%d;"
7866e173d3bSMartin Habets " VFs may not function\n", rc);
7876e173d3bSMartin Habets #endif
7886e173d3bSMartin Habets
7896e173d3bSMartin Habets if (efx->type->rx_restore_rss_contexts)
7906e173d3bSMartin Habets efx->type->rx_restore_rss_contexts(efx);
7916e173d3bSMartin Habets mutex_unlock(&efx->rss_lock);
7926e173d3bSMartin Habets efx->type->filter_table_restore(efx);
7936e173d3bSMartin Habets up_write(&efx->filter_sem);
7946e173d3bSMartin Habets if (efx->type->sriov_reset)
7956e173d3bSMartin Habets efx->type->sriov_reset(efx);
7966e173d3bSMartin Habets
7976e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
7986e173d3bSMartin Habets
79971ad88f6SMartin Habets efx_siena_start_all(efx);
8006e173d3bSMartin Habets
8016e173d3bSMartin Habets if (efx->type->udp_tnl_push_ports)
8026e173d3bSMartin Habets efx->type->udp_tnl_push_ports(efx);
8036e173d3bSMartin Habets
8046e173d3bSMartin Habets return 0;
8056e173d3bSMartin Habets
8066e173d3bSMartin Habets fail:
8076e173d3bSMartin Habets efx->port_initialized = false;
8086e173d3bSMartin Habets
8096e173d3bSMartin Habets mutex_unlock(&efx->rss_lock);
8106e173d3bSMartin Habets up_write(&efx->filter_sem);
8116e173d3bSMartin Habets mutex_unlock(&efx->mac_lock);
8126e173d3bSMartin Habets
8136e173d3bSMartin Habets return rc;
8146e173d3bSMartin Habets }
8156e173d3bSMartin Habets
8166e173d3bSMartin Habets /* Reset the NIC using the specified method. Note that the reset may
8176e173d3bSMartin Habets * fail, in which case the card will be left in an unusable state.
8186e173d3bSMartin Habets *
8196e173d3bSMartin Habets * Caller must hold the rtnl_lock.
8206e173d3bSMartin Habets */
efx_siena_reset(struct efx_nic * efx,enum reset_type method)82171ad88f6SMartin Habets int efx_siena_reset(struct efx_nic *efx, enum reset_type method)
8226e173d3bSMartin Habets {
8236e173d3bSMartin Habets int rc, rc2 = 0;
8246e173d3bSMartin Habets bool disabled;
8256e173d3bSMartin Habets
8266e173d3bSMartin Habets netif_info(efx, drv, efx->net_dev, "resetting (%s)\n",
8276e173d3bSMartin Habets RESET_TYPE(method));
8286e173d3bSMartin Habets
8296e173d3bSMartin Habets efx_device_detach_sync(efx);
83071ad88f6SMartin Habets /* efx_siena_reset_down() grabs locks that prevent recovery on EF100.
8316e173d3bSMartin Habets * EF100 reset is handled in the efx_nic_type callback below.
8326e173d3bSMartin Habets */
8336e173d3bSMartin Habets if (efx_nic_rev(efx) != EFX_REV_EF100)
83471ad88f6SMartin Habets efx_siena_reset_down(efx, method);
8356e173d3bSMartin Habets
8366e173d3bSMartin Habets rc = efx->type->reset(efx, method);
8376e173d3bSMartin Habets if (rc) {
8386e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, "failed to reset hardware\n");
8396e173d3bSMartin Habets goto out;
8406e173d3bSMartin Habets }
8416e173d3bSMartin Habets
8426e173d3bSMartin Habets /* Clear flags for the scopes we covered. We assume the NIC and
8436e173d3bSMartin Habets * driver are now quiescent so that there is no race here.
8446e173d3bSMartin Habets */
8456e173d3bSMartin Habets if (method < RESET_TYPE_MAX_METHOD)
8466e173d3bSMartin Habets efx->reset_pending &= -(1 << (method + 1));
8476e173d3bSMartin Habets else /* it doesn't fit into the well-ordered scope hierarchy */
8486e173d3bSMartin Habets __clear_bit(method, &efx->reset_pending);
8496e173d3bSMartin Habets
8506e173d3bSMartin Habets /* Reinitialise bus-mastering, which may have been turned off before
8516e173d3bSMartin Habets * the reset was scheduled. This is still appropriate, even in the
8526e173d3bSMartin Habets * RESET_TYPE_DISABLE since this driver generally assumes the hardware
8536e173d3bSMartin Habets * can respond to requests.
8546e173d3bSMartin Habets */
8556e173d3bSMartin Habets pci_set_master(efx->pci_dev);
8566e173d3bSMartin Habets
8576e173d3bSMartin Habets out:
8586e173d3bSMartin Habets /* Leave device stopped if necessary */
8596e173d3bSMartin Habets disabled = rc ||
8606e173d3bSMartin Habets method == RESET_TYPE_DISABLE ||
8616e173d3bSMartin Habets method == RESET_TYPE_RECOVER_OR_DISABLE;
8626e173d3bSMartin Habets if (efx_nic_rev(efx) != EFX_REV_EF100)
86371ad88f6SMartin Habets rc2 = efx_siena_reset_up(efx, method, !disabled);
8646e173d3bSMartin Habets if (rc2) {
8656e173d3bSMartin Habets disabled = true;
8666e173d3bSMartin Habets if (!rc)
8676e173d3bSMartin Habets rc = rc2;
8686e173d3bSMartin Habets }
8696e173d3bSMartin Habets
8706e173d3bSMartin Habets if (disabled) {
8716e173d3bSMartin Habets dev_close(efx->net_dev);
8726e173d3bSMartin Habets netif_err(efx, drv, efx->net_dev, "has been disabled\n");
8736e173d3bSMartin Habets efx->state = STATE_DISABLED;
8746e173d3bSMartin Habets } else {
8756e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "reset complete\n");
8766e173d3bSMartin Habets efx_device_attach_if_not_resetting(efx);
8776e173d3bSMartin Habets }
8786e173d3bSMartin Habets return rc;
8796e173d3bSMartin Habets }
8806e173d3bSMartin Habets
8816e173d3bSMartin Habets /* The worker thread exists so that code that cannot sleep can
8826e173d3bSMartin Habets * schedule a reset for later.
8836e173d3bSMartin Habets */
efx_reset_work(struct work_struct * data)8846e173d3bSMartin Habets static void efx_reset_work(struct work_struct *data)
8856e173d3bSMartin Habets {
8866e173d3bSMartin Habets struct efx_nic *efx = container_of(data, struct efx_nic, reset_work);
8876e173d3bSMartin Habets unsigned long pending;
8886e173d3bSMartin Habets enum reset_type method;
8896e173d3bSMartin Habets
8906e173d3bSMartin Habets pending = READ_ONCE(efx->reset_pending);
8916e173d3bSMartin Habets method = fls(pending) - 1;
8926e173d3bSMartin Habets
8936e173d3bSMartin Habets if (method == RESET_TYPE_MC_BIST)
8946e173d3bSMartin Habets efx_wait_for_bist_end(efx);
8956e173d3bSMartin Habets
8966e173d3bSMartin Habets if ((method == RESET_TYPE_RECOVER_OR_DISABLE ||
8976e173d3bSMartin Habets method == RESET_TYPE_RECOVER_OR_ALL) &&
89871ad88f6SMartin Habets efx_siena_try_recovery(efx))
8996e173d3bSMartin Habets return;
9006e173d3bSMartin Habets
9016e173d3bSMartin Habets if (!pending)
9026e173d3bSMartin Habets return;
9036e173d3bSMartin Habets
9046e173d3bSMartin Habets rtnl_lock();
9056e173d3bSMartin Habets
90671ad88f6SMartin Habets /* We checked the state in efx_siena_schedule_reset() but it may
9076e173d3bSMartin Habets * have changed by now. Now that we have the RTNL lock,
9086e173d3bSMartin Habets * it cannot change again.
9096e173d3bSMartin Habets */
9106e173d3bSMartin Habets if (efx->state == STATE_READY)
91171ad88f6SMartin Habets (void)efx_siena_reset(efx, method);
9126e173d3bSMartin Habets
9136e173d3bSMartin Habets rtnl_unlock();
9146e173d3bSMartin Habets }
9156e173d3bSMartin Habets
efx_siena_schedule_reset(struct efx_nic * efx,enum reset_type type)91671ad88f6SMartin Habets void efx_siena_schedule_reset(struct efx_nic *efx, enum reset_type type)
9176e173d3bSMartin Habets {
9186e173d3bSMartin Habets enum reset_type method;
9196e173d3bSMartin Habets
9206e173d3bSMartin Habets if (efx->state == STATE_RECOVERY) {
9216e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev,
9226e173d3bSMartin Habets "recovering: skip scheduling %s reset\n",
9236e173d3bSMartin Habets RESET_TYPE(type));
9246e173d3bSMartin Habets return;
9256e173d3bSMartin Habets }
9266e173d3bSMartin Habets
9276e173d3bSMartin Habets switch (type) {
9286e173d3bSMartin Habets case RESET_TYPE_INVISIBLE:
9296e173d3bSMartin Habets case RESET_TYPE_ALL:
9306e173d3bSMartin Habets case RESET_TYPE_RECOVER_OR_ALL:
9316e173d3bSMartin Habets case RESET_TYPE_WORLD:
9326e173d3bSMartin Habets case RESET_TYPE_DISABLE:
9336e173d3bSMartin Habets case RESET_TYPE_RECOVER_OR_DISABLE:
9346e173d3bSMartin Habets case RESET_TYPE_DATAPATH:
9356e173d3bSMartin Habets case RESET_TYPE_MC_BIST:
9366e173d3bSMartin Habets case RESET_TYPE_MCDI_TIMEOUT:
9376e173d3bSMartin Habets method = type;
9386e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n",
9396e173d3bSMartin Habets RESET_TYPE(method));
9406e173d3bSMartin Habets break;
9416e173d3bSMartin Habets default:
9426e173d3bSMartin Habets method = efx->type->map_reset_reason(type);
9436e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev,
9446e173d3bSMartin Habets "scheduling %s reset for %s\n",
9456e173d3bSMartin Habets RESET_TYPE(method), RESET_TYPE(type));
9466e173d3bSMartin Habets break;
9476e173d3bSMartin Habets }
9486e173d3bSMartin Habets
9496e173d3bSMartin Habets set_bit(method, &efx->reset_pending);
9506e173d3bSMartin Habets smp_mb(); /* ensure we change reset_pending before checking state */
9516e173d3bSMartin Habets
9526e173d3bSMartin Habets /* If we're not READY then just leave the flags set as the cue
9536e173d3bSMartin Habets * to abort probing or reschedule the reset later.
9546e173d3bSMartin Habets */
9556e173d3bSMartin Habets if (READ_ONCE(efx->state) != STATE_READY)
9566e173d3bSMartin Habets return;
9576e173d3bSMartin Habets
9586e173d3bSMartin Habets /* efx_process_channel() will no longer read events once a
9596e173d3bSMartin Habets * reset is scheduled. So switch back to poll'd MCDI completions.
9606e173d3bSMartin Habets */
9614d49e5cdSMartin Habets efx_siena_mcdi_mode_poll(efx);
9626e173d3bSMartin Habets
96371ad88f6SMartin Habets efx_siena_queue_reset_work(efx);
9646e173d3bSMartin Habets }
9656e173d3bSMartin Habets
9666e173d3bSMartin Habets /**************************************************************************
9676e173d3bSMartin Habets *
9686e173d3bSMartin Habets * Dummy NIC operations
9696e173d3bSMartin Habets *
9706e173d3bSMartin Habets * Can be used for some unimplemented operations
9716e173d3bSMartin Habets * Needed so all function pointers are valid and do not have to be tested
9726e173d3bSMartin Habets * before use
9736e173d3bSMartin Habets *
9746e173d3bSMartin Habets **************************************************************************/
efx_siena_port_dummy_op_int(struct efx_nic * efx)97571ad88f6SMartin Habets int efx_siena_port_dummy_op_int(struct efx_nic *efx)
9766e173d3bSMartin Habets {
9776e173d3bSMartin Habets return 0;
9786e173d3bSMartin Habets }
97971ad88f6SMartin Habets
efx_siena_port_dummy_op_void(struct efx_nic * efx)98071ad88f6SMartin Habets void efx_siena_port_dummy_op_void(struct efx_nic *efx) {}
9816e173d3bSMartin Habets
9826e173d3bSMartin Habets /**************************************************************************
9836e173d3bSMartin Habets *
9846e173d3bSMartin Habets * Data housekeeping
9856e173d3bSMartin Habets *
9866e173d3bSMartin Habets **************************************************************************/
9876e173d3bSMartin Habets
9886e173d3bSMartin Habets /* This zeroes out and then fills in the invariants in a struct
9896e173d3bSMartin Habets * efx_nic (including all sub-structures).
9906e173d3bSMartin Habets */
efx_siena_init_struct(struct efx_nic * efx,struct pci_dev * pci_dev,struct net_device * net_dev)99171ad88f6SMartin Habets int efx_siena_init_struct(struct efx_nic *efx,
9926e173d3bSMartin Habets struct pci_dev *pci_dev, struct net_device *net_dev)
9936e173d3bSMartin Habets {
9946e173d3bSMartin Habets int rc = -ENOMEM;
9956e173d3bSMartin Habets
9966e173d3bSMartin Habets /* Initialise common structures */
9976e173d3bSMartin Habets INIT_LIST_HEAD(&efx->node);
9986e173d3bSMartin Habets INIT_LIST_HEAD(&efx->secondary_list);
9996e173d3bSMartin Habets spin_lock_init(&efx->biu_lock);
100065d4b471SMartin Habets #ifdef CONFIG_SFC_SIENA_MTD
10016e173d3bSMartin Habets INIT_LIST_HEAD(&efx->mtd_list);
10026e173d3bSMartin Habets #endif
10036e173d3bSMartin Habets INIT_WORK(&efx->reset_work, efx_reset_work);
10046e173d3bSMartin Habets INIT_DELAYED_WORK(&efx->monitor_work, efx_monitor);
100595e96f77SMartin Habets efx_siena_selftest_async_init(efx);
10066e173d3bSMartin Habets efx->pci_dev = pci_dev;
10076e173d3bSMartin Habets efx->msg_enable = debug;
10086e173d3bSMartin Habets efx->state = STATE_UNINIT;
1009f029c781SWolfram Sang strscpy(efx->name, pci_name(pci_dev), sizeof(efx->name));
10106e173d3bSMartin Habets
10116e173d3bSMartin Habets efx->net_dev = net_dev;
10126e173d3bSMartin Habets efx->rx_prefix_size = efx->type->rx_prefix_size;
10136e173d3bSMartin Habets efx->rx_ip_align =
10146e173d3bSMartin Habets NET_IP_ALIGN ? (efx->rx_prefix_size + NET_IP_ALIGN) % 4 : 0;
10156e173d3bSMartin Habets efx->rx_packet_hash_offset =
10166e173d3bSMartin Habets efx->type->rx_hash_offset - efx->type->rx_prefix_size;
10176e173d3bSMartin Habets efx->rx_packet_ts_offset =
10186e173d3bSMartin Habets efx->type->rx_ts_offset - efx->type->rx_prefix_size;
10196e173d3bSMartin Habets INIT_LIST_HEAD(&efx->rss_context.list);
10206e173d3bSMartin Habets efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
10216e173d3bSMartin Habets mutex_init(&efx->rss_lock);
10226e173d3bSMartin Habets efx->vport_id = EVB_PORT_ID_ASSIGNED;
10236e173d3bSMartin Habets spin_lock_init(&efx->stats_lock);
10246e173d3bSMartin Habets efx->vi_stride = EFX_DEFAULT_VI_STRIDE;
10256e173d3bSMartin Habets efx->num_mac_stats = MC_CMD_MAC_NSTATS;
10266e173d3bSMartin Habets BUILD_BUG_ON(MC_CMD_MAC_NSTATS - 1 != MC_CMD_MAC_GENERATION_END);
10276e173d3bSMartin Habets mutex_init(&efx->mac_lock);
10286e173d3bSMartin Habets init_rwsem(&efx->filter_sem);
10296e173d3bSMartin Habets #ifdef CONFIG_RFS_ACCEL
10306e173d3bSMartin Habets mutex_init(&efx->rps_mutex);
10316e173d3bSMartin Habets spin_lock_init(&efx->rps_hash_lock);
10326e173d3bSMartin Habets /* Failure to allocate is not fatal, but may degrade ARFS performance */
10336e173d3bSMartin Habets efx->rps_hash_table = kcalloc(EFX_ARFS_HASH_TABLE_SIZE,
10346e173d3bSMartin Habets sizeof(*efx->rps_hash_table), GFP_KERNEL);
10356e173d3bSMartin Habets #endif
10366e173d3bSMartin Habets efx->mdio.dev = net_dev;
10376e173d3bSMartin Habets INIT_WORK(&efx->mac_work, efx_mac_work);
10386e173d3bSMartin Habets init_waitqueue_head(&efx->flush_wq);
10396e173d3bSMartin Habets
10406e173d3bSMartin Habets efx->tx_queues_per_channel = 1;
10416e173d3bSMartin Habets efx->rxq_entries = EFX_DEFAULT_DMAQ_SIZE;
10426e173d3bSMartin Habets efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
10436e173d3bSMartin Habets
10446e173d3bSMartin Habets efx->mem_bar = UINT_MAX;
10456e173d3bSMartin Habets
104671ad88f6SMartin Habets rc = efx_siena_init_channels(efx);
10476e173d3bSMartin Habets if (rc)
10486e173d3bSMartin Habets goto fail;
10496e173d3bSMartin Habets
10506e173d3bSMartin Habets /* Would be good to use the net_dev name, but we're too early */
10516e173d3bSMartin Habets snprintf(efx->workqueue_name, sizeof(efx->workqueue_name), "sfc%s",
10526e173d3bSMartin Habets pci_name(pci_dev));
10536e173d3bSMartin Habets efx->workqueue = create_singlethread_workqueue(efx->workqueue_name);
10546e173d3bSMartin Habets if (!efx->workqueue) {
10556e173d3bSMartin Habets rc = -ENOMEM;
10566e173d3bSMartin Habets goto fail;
10576e173d3bSMartin Habets }
10586e173d3bSMartin Habets
10596e173d3bSMartin Habets return 0;
10606e173d3bSMartin Habets
10616e173d3bSMartin Habets fail:
106271ad88f6SMartin Habets efx_siena_fini_struct(efx);
10636e173d3bSMartin Habets return rc;
10646e173d3bSMartin Habets }
10656e173d3bSMartin Habets
efx_siena_fini_struct(struct efx_nic * efx)106671ad88f6SMartin Habets void efx_siena_fini_struct(struct efx_nic *efx)
10676e173d3bSMartin Habets {
10686e173d3bSMartin Habets #ifdef CONFIG_RFS_ACCEL
10696e173d3bSMartin Habets kfree(efx->rps_hash_table);
10706e173d3bSMartin Habets #endif
10716e173d3bSMartin Habets
107271ad88f6SMartin Habets efx_siena_fini_channels(efx);
10736e173d3bSMartin Habets
10746e173d3bSMartin Habets kfree(efx->vpd_sn);
10756e173d3bSMartin Habets
10766e173d3bSMartin Habets if (efx->workqueue) {
10776e173d3bSMartin Habets destroy_workqueue(efx->workqueue);
10786e173d3bSMartin Habets efx->workqueue = NULL;
10796e173d3bSMartin Habets }
10806e173d3bSMartin Habets }
10816e173d3bSMartin Habets
10826e173d3bSMartin Habets /* This configures the PCI device to enable I/O and DMA. */
efx_siena_init_io(struct efx_nic * efx,int bar,dma_addr_t dma_mask,unsigned int mem_map_size)108371ad88f6SMartin Habets int efx_siena_init_io(struct efx_nic *efx, int bar, dma_addr_t dma_mask,
10846e173d3bSMartin Habets unsigned int mem_map_size)
10856e173d3bSMartin Habets {
10866e173d3bSMartin Habets struct pci_dev *pci_dev = efx->pci_dev;
10876e173d3bSMartin Habets int rc;
10886e173d3bSMartin Habets
10896e173d3bSMartin Habets efx->mem_bar = UINT_MAX;
10906e173d3bSMartin Habets
10916e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev, "initialising I/O bar=%d\n", bar);
10926e173d3bSMartin Habets
10936e173d3bSMartin Habets rc = pci_enable_device(pci_dev);
10946e173d3bSMartin Habets if (rc) {
10956e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev,
10966e173d3bSMartin Habets "failed to enable PCI device\n");
10976e173d3bSMartin Habets goto fail1;
10986e173d3bSMartin Habets }
10996e173d3bSMartin Habets
11006e173d3bSMartin Habets pci_set_master(pci_dev);
11016e173d3bSMartin Habets
11026e173d3bSMartin Habets rc = dma_set_mask_and_coherent(&pci_dev->dev, dma_mask);
11036e173d3bSMartin Habets if (rc) {
11046e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev,
11056e173d3bSMartin Habets "could not find a suitable DMA mask\n");
11066e173d3bSMartin Habets goto fail2;
11076e173d3bSMartin Habets }
11086e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev,
11096e173d3bSMartin Habets "using DMA mask %llx\n", (unsigned long long)dma_mask);
11106e173d3bSMartin Habets
11116e173d3bSMartin Habets efx->membase_phys = pci_resource_start(efx->pci_dev, bar);
11126e173d3bSMartin Habets if (!efx->membase_phys) {
11136e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev,
11146e173d3bSMartin Habets "ERROR: No BAR%d mapping from the BIOS. "
11156e173d3bSMartin Habets "Try pci=realloc on the kernel command line\n", bar);
11166e173d3bSMartin Habets rc = -ENODEV;
11176e173d3bSMartin Habets goto fail3;
11186e173d3bSMartin Habets }
11196e173d3bSMartin Habets
11206e173d3bSMartin Habets rc = pci_request_region(pci_dev, bar, "sfc");
11216e173d3bSMartin Habets if (rc) {
11226e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev,
11236e173d3bSMartin Habets "request for memory BAR[%d] failed\n", bar);
11246e173d3bSMartin Habets rc = -EIO;
11256e173d3bSMartin Habets goto fail3;
11266e173d3bSMartin Habets }
11276e173d3bSMartin Habets efx->mem_bar = bar;
11286e173d3bSMartin Habets efx->membase = ioremap(efx->membase_phys, mem_map_size);
11296e173d3bSMartin Habets if (!efx->membase) {
11306e173d3bSMartin Habets netif_err(efx, probe, efx->net_dev,
11316e173d3bSMartin Habets "could not map memory BAR[%d] at %llx+%x\n", bar,
11326e173d3bSMartin Habets (unsigned long long)efx->membase_phys, mem_map_size);
11336e173d3bSMartin Habets rc = -ENOMEM;
11346e173d3bSMartin Habets goto fail4;
11356e173d3bSMartin Habets }
11366e173d3bSMartin Habets netif_dbg(efx, probe, efx->net_dev,
11376e173d3bSMartin Habets "memory BAR[%d] at %llx+%x (virtual %p)\n", bar,
11386e173d3bSMartin Habets (unsigned long long)efx->membase_phys, mem_map_size,
11396e173d3bSMartin Habets efx->membase);
11406e173d3bSMartin Habets
11416e173d3bSMartin Habets return 0;
11426e173d3bSMartin Habets
11436e173d3bSMartin Habets fail4:
11446e173d3bSMartin Habets pci_release_region(efx->pci_dev, bar);
11456e173d3bSMartin Habets fail3:
11466e173d3bSMartin Habets efx->membase_phys = 0;
11476e173d3bSMartin Habets fail2:
11486e173d3bSMartin Habets pci_disable_device(efx->pci_dev);
11496e173d3bSMartin Habets fail1:
11506e173d3bSMartin Habets return rc;
11516e173d3bSMartin Habets }
11526e173d3bSMartin Habets
efx_siena_fini_io(struct efx_nic * efx)115371ad88f6SMartin Habets void efx_siena_fini_io(struct efx_nic *efx)
11546e173d3bSMartin Habets {
11556e173d3bSMartin Habets netif_dbg(efx, drv, efx->net_dev, "shutting down I/O\n");
11566e173d3bSMartin Habets
11576e173d3bSMartin Habets if (efx->membase) {
11586e173d3bSMartin Habets iounmap(efx->membase);
11596e173d3bSMartin Habets efx->membase = NULL;
11606e173d3bSMartin Habets }
11616e173d3bSMartin Habets
11626e173d3bSMartin Habets if (efx->membase_phys) {
11636e173d3bSMartin Habets pci_release_region(efx->pci_dev, efx->mem_bar);
11646e173d3bSMartin Habets efx->membase_phys = 0;
11656e173d3bSMartin Habets efx->mem_bar = UINT_MAX;
11666e173d3bSMartin Habets }
11676e173d3bSMartin Habets
11686e173d3bSMartin Habets /* Don't disable bus-mastering if VFs are assigned */
11696e173d3bSMartin Habets if (!pci_vfs_assigned(efx->pci_dev))
11706e173d3bSMartin Habets pci_disable_device(efx->pci_dev);
11716e173d3bSMartin Habets }
11726e173d3bSMartin Habets
117358b6b3d5SMartin Habets #ifdef CONFIG_SFC_SIENA_MCDI_LOGGING
mcdi_logging_show(struct device * dev,struct device_attribute * attr,char * buf)11746e173d3bSMartin Habets static ssize_t mcdi_logging_show(struct device *dev,
11756e173d3bSMartin Habets struct device_attribute *attr,
11766e173d3bSMartin Habets char *buf)
11776e173d3bSMartin Habets {
11786e173d3bSMartin Habets struct efx_nic *efx = dev_get_drvdata(dev);
11796e173d3bSMartin Habets struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
11806e173d3bSMartin Habets
1181*1ab586f5Sye xingchen return sysfs_emit(buf, "%d\n", mcdi->logging_enabled);
11826e173d3bSMartin Habets }
11836e173d3bSMartin Habets
mcdi_logging_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)11846e173d3bSMartin Habets static ssize_t mcdi_logging_store(struct device *dev,
11856e173d3bSMartin Habets struct device_attribute *attr,
11866e173d3bSMartin Habets const char *buf, size_t count)
11876e173d3bSMartin Habets {
11886e173d3bSMartin Habets struct efx_nic *efx = dev_get_drvdata(dev);
11896e173d3bSMartin Habets struct efx_mcdi_iface *mcdi = efx_mcdi(efx);
11906e173d3bSMartin Habets bool enable = count > 0 && *buf != '0';
11916e173d3bSMartin Habets
11926e173d3bSMartin Habets mcdi->logging_enabled = enable;
11936e173d3bSMartin Habets return count;
11946e173d3bSMartin Habets }
11956e173d3bSMartin Habets
11966e173d3bSMartin Habets static DEVICE_ATTR_RW(mcdi_logging);
11976e173d3bSMartin Habets
efx_siena_init_mcdi_logging(struct efx_nic * efx)119871ad88f6SMartin Habets void efx_siena_init_mcdi_logging(struct efx_nic *efx)
11996e173d3bSMartin Habets {
12006e173d3bSMartin Habets int rc = device_create_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging);
12016e173d3bSMartin Habets
12026e173d3bSMartin Habets if (rc) {
12036e173d3bSMartin Habets netif_warn(efx, drv, efx->net_dev,
12046e173d3bSMartin Habets "failed to init net dev attributes\n");
12056e173d3bSMartin Habets }
12066e173d3bSMartin Habets }
12076e173d3bSMartin Habets
efx_siena_fini_mcdi_logging(struct efx_nic * efx)120871ad88f6SMartin Habets void efx_siena_fini_mcdi_logging(struct efx_nic *efx)
12096e173d3bSMartin Habets {
12106e173d3bSMartin Habets device_remove_file(&efx->pci_dev->dev, &dev_attr_mcdi_logging);
12116e173d3bSMartin Habets }
12126e173d3bSMartin Habets #endif
12136e173d3bSMartin Habets
12146e173d3bSMartin Habets /* A PCI error affecting this device was detected.
12156e173d3bSMartin Habets * At this point MMIO and DMA may be disabled.
12166e173d3bSMartin Habets * Stop the software path and request a slot reset.
12176e173d3bSMartin Habets */
efx_io_error_detected(struct pci_dev * pdev,pci_channel_state_t state)12186e173d3bSMartin Habets static pci_ers_result_t efx_io_error_detected(struct pci_dev *pdev,
12196e173d3bSMartin Habets pci_channel_state_t state)
12206e173d3bSMartin Habets {
12216e173d3bSMartin Habets pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
12226e173d3bSMartin Habets struct efx_nic *efx = pci_get_drvdata(pdev);
12236e173d3bSMartin Habets
12246e173d3bSMartin Habets if (state == pci_channel_io_perm_failure)
12256e173d3bSMartin Habets return PCI_ERS_RESULT_DISCONNECT;
12266e173d3bSMartin Habets
12276e173d3bSMartin Habets rtnl_lock();
12286e173d3bSMartin Habets
12296e173d3bSMartin Habets if (efx->state != STATE_DISABLED) {
12306e173d3bSMartin Habets efx->state = STATE_RECOVERY;
12316e173d3bSMartin Habets efx->reset_pending = 0;
12326e173d3bSMartin Habets
12336e173d3bSMartin Habets efx_device_detach_sync(efx);
12346e173d3bSMartin Habets
123571ad88f6SMartin Habets efx_siena_stop_all(efx);
123671ad88f6SMartin Habets efx_siena_disable_interrupts(efx);
12376e173d3bSMartin Habets
12386e173d3bSMartin Habets status = PCI_ERS_RESULT_NEED_RESET;
12396e173d3bSMartin Habets } else {
12406e173d3bSMartin Habets /* If the interface is disabled we don't want to do anything
12416e173d3bSMartin Habets * with it.
12426e173d3bSMartin Habets */
12436e173d3bSMartin Habets status = PCI_ERS_RESULT_RECOVERED;
12446e173d3bSMartin Habets }
12456e173d3bSMartin Habets
12466e173d3bSMartin Habets rtnl_unlock();
12476e173d3bSMartin Habets
12486e173d3bSMartin Habets pci_disable_device(pdev);
12496e173d3bSMartin Habets
12506e173d3bSMartin Habets return status;
12516e173d3bSMartin Habets }
12526e173d3bSMartin Habets
12536e173d3bSMartin Habets /* Fake a successful reset, which will be performed later in efx_io_resume. */
efx_io_slot_reset(struct pci_dev * pdev)12546e173d3bSMartin Habets static pci_ers_result_t efx_io_slot_reset(struct pci_dev *pdev)
12556e173d3bSMartin Habets {
12566e173d3bSMartin Habets struct efx_nic *efx = pci_get_drvdata(pdev);
12576e173d3bSMartin Habets pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
12586e173d3bSMartin Habets
12596e173d3bSMartin Habets if (pci_enable_device(pdev)) {
12606e173d3bSMartin Habets netif_err(efx, hw, efx->net_dev,
12616e173d3bSMartin Habets "Cannot re-enable PCI device after reset.\n");
12626e173d3bSMartin Habets status = PCI_ERS_RESULT_DISCONNECT;
12636e173d3bSMartin Habets }
12646e173d3bSMartin Habets
12656e173d3bSMartin Habets return status;
12666e173d3bSMartin Habets }
12676e173d3bSMartin Habets
12686e173d3bSMartin Habets /* Perform the actual reset and resume I/O operations. */
efx_io_resume(struct pci_dev * pdev)12696e173d3bSMartin Habets static void efx_io_resume(struct pci_dev *pdev)
12706e173d3bSMartin Habets {
12716e173d3bSMartin Habets struct efx_nic *efx = pci_get_drvdata(pdev);
12726e173d3bSMartin Habets int rc;
12736e173d3bSMartin Habets
12746e173d3bSMartin Habets rtnl_lock();
12756e173d3bSMartin Habets
12766e173d3bSMartin Habets if (efx->state == STATE_DISABLED)
12776e173d3bSMartin Habets goto out;
12786e173d3bSMartin Habets
127971ad88f6SMartin Habets rc = efx_siena_reset(efx, RESET_TYPE_ALL);
12806e173d3bSMartin Habets if (rc) {
12816e173d3bSMartin Habets netif_err(efx, hw, efx->net_dev,
128271ad88f6SMartin Habets "efx_siena_reset failed after PCI error (%d)\n", rc);
12836e173d3bSMartin Habets } else {
12846e173d3bSMartin Habets efx->state = STATE_READY;
12856e173d3bSMartin Habets netif_dbg(efx, hw, efx->net_dev,
12866e173d3bSMartin Habets "Done resetting and resuming IO after PCI error.\n");
12876e173d3bSMartin Habets }
12886e173d3bSMartin Habets
12896e173d3bSMartin Habets out:
12906e173d3bSMartin Habets rtnl_unlock();
12916e173d3bSMartin Habets }
12926e173d3bSMartin Habets
12936e173d3bSMartin Habets /* For simplicity and reliability, we always require a slot reset and try to
12946e173d3bSMartin Habets * reset the hardware when a pci error affecting the device is detected.
12956e173d3bSMartin Habets * We leave both the link_reset and mmio_enabled callback unimplemented:
12966e173d3bSMartin Habets * with our request for slot reset the mmio_enabled callback will never be
12976e173d3bSMartin Habets * called, and the link_reset callback is not used by AER or EEH mechanisms.
12986e173d3bSMartin Habets */
129971ad88f6SMartin Habets const struct pci_error_handlers efx_siena_err_handlers = {
13006e173d3bSMartin Habets .error_detected = efx_io_error_detected,
13016e173d3bSMartin Habets .slot_reset = efx_io_slot_reset,
13026e173d3bSMartin Habets .resume = efx_io_resume,
13036e173d3bSMartin Habets };
13046e173d3bSMartin Habets
13056e173d3bSMartin Habets /* Determine whether the NIC will be able to handle TX offloads for a given
13066e173d3bSMartin Habets * encapsulated packet.
13076e173d3bSMartin Habets */
efx_can_encap_offloads(struct efx_nic * efx,struct sk_buff * skb)13086e173d3bSMartin Habets static bool efx_can_encap_offloads(struct efx_nic *efx, struct sk_buff *skb)
13096e173d3bSMartin Habets {
13106e173d3bSMartin Habets struct gre_base_hdr *greh;
13116e173d3bSMartin Habets __be16 dst_port;
13126e173d3bSMartin Habets u8 ipproto;
13136e173d3bSMartin Habets
13146e173d3bSMartin Habets /* Does the NIC support encap offloads?
13156e173d3bSMartin Habets * If not, we should never get here, because we shouldn't have
13166e173d3bSMartin Habets * advertised encap offload feature flags in the first place.
13176e173d3bSMartin Habets */
13186e173d3bSMartin Habets if (WARN_ON_ONCE(!efx->type->udp_tnl_has_port))
13196e173d3bSMartin Habets return false;
13206e173d3bSMartin Habets
13216e173d3bSMartin Habets /* Determine encapsulation protocol in use */
13226e173d3bSMartin Habets switch (skb->protocol) {
13236e173d3bSMartin Habets case htons(ETH_P_IP):
13246e173d3bSMartin Habets ipproto = ip_hdr(skb)->protocol;
13256e173d3bSMartin Habets break;
13266e173d3bSMartin Habets case htons(ETH_P_IPV6):
13276e173d3bSMartin Habets /* If there are extension headers, this will cause us to
13286e173d3bSMartin Habets * think we can't offload something that we maybe could have.
13296e173d3bSMartin Habets */
13306e173d3bSMartin Habets ipproto = ipv6_hdr(skb)->nexthdr;
13316e173d3bSMartin Habets break;
13326e173d3bSMartin Habets default:
13336e173d3bSMartin Habets /* Not IP, so can't offload it */
13346e173d3bSMartin Habets return false;
13356e173d3bSMartin Habets }
13366e173d3bSMartin Habets switch (ipproto) {
13376e173d3bSMartin Habets case IPPROTO_GRE:
13386e173d3bSMartin Habets /* We support NVGRE but not IP over GRE or random gretaps.
13396e173d3bSMartin Habets * Specifically, the NIC will accept GRE as encapsulated if
13406e173d3bSMartin Habets * the inner protocol is Ethernet, but only handle it
13416e173d3bSMartin Habets * correctly if the GRE header is 8 bytes long. Moreover,
13426e173d3bSMartin Habets * it will not update the Checksum or Sequence Number fields
13436e173d3bSMartin Habets * if they are present. (The Routing Present flag,
13446e173d3bSMartin Habets * GRE_ROUTING, cannot be set else the header would be more
13456e173d3bSMartin Habets * than 8 bytes long; so we don't have to worry about it.)
13466e173d3bSMartin Habets */
13476e173d3bSMartin Habets if (skb->inner_protocol_type != ENCAP_TYPE_ETHER)
13486e173d3bSMartin Habets return false;
13496e173d3bSMartin Habets if (ntohs(skb->inner_protocol) != ETH_P_TEB)
13506e173d3bSMartin Habets return false;
13516e173d3bSMartin Habets if (skb_inner_mac_header(skb) - skb_transport_header(skb) != 8)
13526e173d3bSMartin Habets return false;
13536e173d3bSMartin Habets greh = (struct gre_base_hdr *)skb_transport_header(skb);
13546e173d3bSMartin Habets return !(greh->flags & (GRE_CSUM | GRE_SEQ));
13556e173d3bSMartin Habets case IPPROTO_UDP:
13566e173d3bSMartin Habets /* If the port is registered for a UDP tunnel, we assume the
13576e173d3bSMartin Habets * packet is for that tunnel, and the NIC will handle it as
13586e173d3bSMartin Habets * such. If not, the NIC won't know what to do with it.
13596e173d3bSMartin Habets */
13606e173d3bSMartin Habets dst_port = udp_hdr(skb)->dest;
13616e173d3bSMartin Habets return efx->type->udp_tnl_has_port(efx, dst_port);
13626e173d3bSMartin Habets default:
13636e173d3bSMartin Habets return false;
13646e173d3bSMartin Habets }
13656e173d3bSMartin Habets }
13666e173d3bSMartin Habets
efx_siena_features_check(struct sk_buff * skb,struct net_device * dev,netdev_features_t features)136771ad88f6SMartin Habets netdev_features_t efx_siena_features_check(struct sk_buff *skb,
136871ad88f6SMartin Habets struct net_device *dev,
13696e173d3bSMartin Habets netdev_features_t features)
13706e173d3bSMartin Habets {
13716e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(dev);
13726e173d3bSMartin Habets
13736e173d3bSMartin Habets if (skb->encapsulation) {
13746e173d3bSMartin Habets if (features & NETIF_F_GSO_MASK)
13756e173d3bSMartin Habets /* Hardware can only do TSO with at most 208 bytes
13766e173d3bSMartin Habets * of headers.
13776e173d3bSMartin Habets */
13786e173d3bSMartin Habets if (skb_inner_transport_offset(skb) >
13796e173d3bSMartin Habets EFX_TSO2_MAX_HDRLEN)
13806e173d3bSMartin Habets features &= ~(NETIF_F_GSO_MASK);
13816e173d3bSMartin Habets if (features & (NETIF_F_GSO_MASK | NETIF_F_CSUM_MASK))
13826e173d3bSMartin Habets if (!efx_can_encap_offloads(efx, skb))
13836e173d3bSMartin Habets features &= ~(NETIF_F_GSO_MASK |
13846e173d3bSMartin Habets NETIF_F_CSUM_MASK);
13856e173d3bSMartin Habets }
13866e173d3bSMartin Habets return features;
13876e173d3bSMartin Habets }
13886e173d3bSMartin Habets
efx_siena_get_phys_port_id(struct net_device * net_dev,struct netdev_phys_item_id * ppid)138971ad88f6SMartin Habets int efx_siena_get_phys_port_id(struct net_device *net_dev,
13906e173d3bSMartin Habets struct netdev_phys_item_id *ppid)
13916e173d3bSMartin Habets {
13926e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev);
13936e173d3bSMartin Habets
13946e173d3bSMartin Habets if (efx->type->get_phys_port_id)
13956e173d3bSMartin Habets return efx->type->get_phys_port_id(efx, ppid);
13966e173d3bSMartin Habets else
13976e173d3bSMartin Habets return -EOPNOTSUPP;
13986e173d3bSMartin Habets }
13996e173d3bSMartin Habets
efx_siena_get_phys_port_name(struct net_device * net_dev,char * name,size_t len)140071ad88f6SMartin Habets int efx_siena_get_phys_port_name(struct net_device *net_dev,
140171ad88f6SMartin Habets char *name, size_t len)
14026e173d3bSMartin Habets {
14036e173d3bSMartin Habets struct efx_nic *efx = netdev_priv(net_dev);
14046e173d3bSMartin Habets
14056e173d3bSMartin Habets if (snprintf(name, len, "p%u", efx->port_num) >= len)
14066e173d3bSMartin Habets return -EINVAL;
14076e173d3bSMartin Habets return 0;
14086e173d3bSMartin Habets }
1409