106bc1977SAndrew Rybchenko /*- 2244cfa79SAndrew Rybchenko * BSD LICENSE 3244cfa79SAndrew Rybchenko * 4244cfa79SAndrew Rybchenko * Copyright (c) 2016-2017 Solarflare Communications Inc. 506bc1977SAndrew Rybchenko * All rights reserved. 606bc1977SAndrew Rybchenko * 706bc1977SAndrew Rybchenko * This software was jointly developed between OKTET Labs (under contract 806bc1977SAndrew Rybchenko * for Solarflare) and Solarflare Communications, Inc. 906bc1977SAndrew Rybchenko * 1006bc1977SAndrew Rybchenko * Redistribution and use in source and binary forms, with or without 1106bc1977SAndrew Rybchenko * modification, are permitted provided that the following conditions are met: 1206bc1977SAndrew Rybchenko * 1306bc1977SAndrew Rybchenko * 1. Redistributions of source code must retain the above copyright notice, 1406bc1977SAndrew Rybchenko * this list of conditions and the following disclaimer. 1506bc1977SAndrew Rybchenko * 2. Redistributions in binary form must reproduce the above copyright notice, 1606bc1977SAndrew Rybchenko * this list of conditions and the following disclaimer in the documentation 1706bc1977SAndrew Rybchenko * and/or other materials provided with the distribution. 1806bc1977SAndrew Rybchenko * 1906bc1977SAndrew Rybchenko * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2006bc1977SAndrew Rybchenko * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 2106bc1977SAndrew Rybchenko * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2206bc1977SAndrew Rybchenko * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 2306bc1977SAndrew Rybchenko * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2406bc1977SAndrew Rybchenko * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2506bc1977SAndrew Rybchenko * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2606bc1977SAndrew Rybchenko * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2706bc1977SAndrew Rybchenko * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2806bc1977SAndrew Rybchenko * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 2906bc1977SAndrew Rybchenko * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3006bc1977SAndrew Rybchenko */ 3106bc1977SAndrew Rybchenko 323b809c27SAndrew Rybchenko /* 333b809c27SAndrew Rybchenko * At the momemt of writing DPDK v16.07 has notion of two types of 343b809c27SAndrew Rybchenko * interrupts: LSC (link status change) and RXQ (receive indication). 353b809c27SAndrew Rybchenko * It allows to register interrupt callback for entire device which is 363b809c27SAndrew Rybchenko * not intended to be used for receive indication (i.e. link status 373b809c27SAndrew Rybchenko * change indication only). The handler has no information which HW 383b809c27SAndrew Rybchenko * interrupt has triggered it, so we don't know which event queue should 393b809c27SAndrew Rybchenko * be polled/reprimed (except qmask in the case of legacy line interrupt). 403b809c27SAndrew Rybchenko */ 413b809c27SAndrew Rybchenko 423b809c27SAndrew Rybchenko #include <rte_common.h> 433b809c27SAndrew Rybchenko #include <rte_interrupts.h> 443b809c27SAndrew Rybchenko 4506bc1977SAndrew Rybchenko #include "efx.h" 4606bc1977SAndrew Rybchenko 4706bc1977SAndrew Rybchenko #include "sfc.h" 4806bc1977SAndrew Rybchenko #include "sfc_log.h" 493b809c27SAndrew Rybchenko #include "sfc_ev.h" 503b809c27SAndrew Rybchenko 513b809c27SAndrew Rybchenko static void 523b809c27SAndrew Rybchenko sfc_intr_handle_mgmt_evq(struct sfc_adapter *sa) 533b809c27SAndrew Rybchenko { 543b809c27SAndrew Rybchenko struct sfc_evq *evq; 553b809c27SAndrew Rybchenko 563b809c27SAndrew Rybchenko rte_spinlock_lock(&sa->mgmt_evq_lock); 573b809c27SAndrew Rybchenko 586caeec47SAndrew Rybchenko evq = sa->mgmt_evq; 593b809c27SAndrew Rybchenko 603b809c27SAndrew Rybchenko if (evq->init_state != SFC_EVQ_STARTED) { 613b809c27SAndrew Rybchenko sfc_log_init(sa, "interrupt on stopped EVQ %u", evq->evq_index); 623b809c27SAndrew Rybchenko } else { 633b809c27SAndrew Rybchenko sfc_ev_qpoll(evq); 643b809c27SAndrew Rybchenko 653b809c27SAndrew Rybchenko if (sfc_ev_qprime(evq) != 0) 663b809c27SAndrew Rybchenko sfc_err(sa, "cannot prime EVQ %u", evq->evq_index); 673b809c27SAndrew Rybchenko } 683b809c27SAndrew Rybchenko 693b809c27SAndrew Rybchenko rte_spinlock_unlock(&sa->mgmt_evq_lock); 703b809c27SAndrew Rybchenko } 713b809c27SAndrew Rybchenko 723b809c27SAndrew Rybchenko static void 73c23a1a30SQi Zhang sfc_intr_line_handler(void *cb_arg) 743b809c27SAndrew Rybchenko { 753b809c27SAndrew Rybchenko struct sfc_adapter *sa = (struct sfc_adapter *)cb_arg; 763b809c27SAndrew Rybchenko efx_nic_t *enp = sa->nic; 773b809c27SAndrew Rybchenko boolean_t fatal; 783b809c27SAndrew Rybchenko uint32_t qmask; 793b809c27SAndrew Rybchenko unsigned int lsc_seq = sa->port.lsc_seq; 80c0802544SFerruh Yigit struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev); 813b809c27SAndrew Rybchenko 823b809c27SAndrew Rybchenko sfc_log_init(sa, "entry"); 833b809c27SAndrew Rybchenko 843b809c27SAndrew Rybchenko if (sa->state != SFC_ADAPTER_STARTED && 853b809c27SAndrew Rybchenko sa->state != SFC_ADAPTER_STARTING && 863b809c27SAndrew Rybchenko sa->state != SFC_ADAPTER_STOPPING) { 873b809c27SAndrew Rybchenko sfc_log_init(sa, 883b809c27SAndrew Rybchenko "interrupt on stopped adapter, don't reenable"); 893b809c27SAndrew Rybchenko goto exit; 903b809c27SAndrew Rybchenko } 913b809c27SAndrew Rybchenko 923b809c27SAndrew Rybchenko efx_intr_status_line(enp, &fatal, &qmask); 933b809c27SAndrew Rybchenko if (fatal) { 943b809c27SAndrew Rybchenko (void)efx_intr_disable(enp); 953b809c27SAndrew Rybchenko (void)efx_intr_fatal(enp); 963b809c27SAndrew Rybchenko sfc_err(sa, "fatal, interrupts disabled"); 973b809c27SAndrew Rybchenko goto exit; 983b809c27SAndrew Rybchenko } 993b809c27SAndrew Rybchenko 1003b809c27SAndrew Rybchenko if (qmask & (1 << sa->mgmt_evq_index)) 1013b809c27SAndrew Rybchenko sfc_intr_handle_mgmt_evq(sa); 1023b809c27SAndrew Rybchenko 103c23a1a30SQi Zhang if (rte_intr_enable(&pci_dev->intr_handle) != 0) 1043b809c27SAndrew Rybchenko sfc_err(sa, "cannot reenable interrupts"); 1053b809c27SAndrew Rybchenko 1063b809c27SAndrew Rybchenko sfc_log_init(sa, "done"); 1073b809c27SAndrew Rybchenko 1083b809c27SAndrew Rybchenko exit: 1093b809c27SAndrew Rybchenko if (lsc_seq != sa->port.lsc_seq) { 1103b809c27SAndrew Rybchenko sfc_info(sa, "link status change event: link %s", 1113b809c27SAndrew Rybchenko sa->eth_dev->data->dev_link.link_status ? 1123b809c27SAndrew Rybchenko "UP" : "DOWN"); 1133b809c27SAndrew Rybchenko _rte_eth_dev_callback_process(sa->eth_dev, 114*d6af1a13SBernard Iremonger RTE_ETH_EVENT_INTR_LSC, 115*d6af1a13SBernard Iremonger NULL, NULL); 1163b809c27SAndrew Rybchenko } 1173b809c27SAndrew Rybchenko } 1183b809c27SAndrew Rybchenko 1193b809c27SAndrew Rybchenko static void 120c23a1a30SQi Zhang sfc_intr_message_handler(void *cb_arg) 1213b809c27SAndrew Rybchenko { 1223b809c27SAndrew Rybchenko struct sfc_adapter *sa = (struct sfc_adapter *)cb_arg; 1233b809c27SAndrew Rybchenko efx_nic_t *enp = sa->nic; 1243b809c27SAndrew Rybchenko boolean_t fatal; 1253b809c27SAndrew Rybchenko unsigned int lsc_seq = sa->port.lsc_seq; 126c0802544SFerruh Yigit struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev); 1273b809c27SAndrew Rybchenko 1283b809c27SAndrew Rybchenko sfc_log_init(sa, "entry"); 1293b809c27SAndrew Rybchenko 1303b809c27SAndrew Rybchenko if (sa->state != SFC_ADAPTER_STARTED && 1313b809c27SAndrew Rybchenko sa->state != SFC_ADAPTER_STARTING && 1323b809c27SAndrew Rybchenko sa->state != SFC_ADAPTER_STOPPING) { 1333b809c27SAndrew Rybchenko sfc_log_init(sa, "adapter not-started, don't reenable"); 1343b809c27SAndrew Rybchenko goto exit; 1353b809c27SAndrew Rybchenko } 1363b809c27SAndrew Rybchenko 1373b809c27SAndrew Rybchenko efx_intr_status_message(enp, sa->mgmt_evq_index, &fatal); 1383b809c27SAndrew Rybchenko if (fatal) { 1393b809c27SAndrew Rybchenko (void)efx_intr_disable(enp); 1403b809c27SAndrew Rybchenko (void)efx_intr_fatal(enp); 1413b809c27SAndrew Rybchenko sfc_err(sa, "fatal, interrupts disabled"); 1423b809c27SAndrew Rybchenko goto exit; 1433b809c27SAndrew Rybchenko } 1443b809c27SAndrew Rybchenko 1453b809c27SAndrew Rybchenko sfc_intr_handle_mgmt_evq(sa); 1463b809c27SAndrew Rybchenko 147c23a1a30SQi Zhang if (rte_intr_enable(&pci_dev->intr_handle) != 0) 1483b809c27SAndrew Rybchenko sfc_err(sa, "cannot reenable interrupts"); 1493b809c27SAndrew Rybchenko 1503b809c27SAndrew Rybchenko sfc_log_init(sa, "done"); 1513b809c27SAndrew Rybchenko 1523b809c27SAndrew Rybchenko exit: 1533b809c27SAndrew Rybchenko if (lsc_seq != sa->port.lsc_seq) { 1543b809c27SAndrew Rybchenko sfc_info(sa, "link status change event"); 1553b809c27SAndrew Rybchenko _rte_eth_dev_callback_process(sa->eth_dev, 156*d6af1a13SBernard Iremonger RTE_ETH_EVENT_INTR_LSC, 157*d6af1a13SBernard Iremonger NULL, NULL); 1583b809c27SAndrew Rybchenko } 1593b809c27SAndrew Rybchenko } 16006bc1977SAndrew Rybchenko 16106bc1977SAndrew Rybchenko int 16206bc1977SAndrew Rybchenko sfc_intr_start(struct sfc_adapter *sa) 16306bc1977SAndrew Rybchenko { 16406bc1977SAndrew Rybchenko struct sfc_intr *intr = &sa->intr; 16506bc1977SAndrew Rybchenko struct rte_intr_handle *intr_handle; 16606bc1977SAndrew Rybchenko struct rte_pci_device *pci_dev; 16706bc1977SAndrew Rybchenko int rc; 16806bc1977SAndrew Rybchenko 16906bc1977SAndrew Rybchenko sfc_log_init(sa, "entry"); 17006bc1977SAndrew Rybchenko 17106bc1977SAndrew Rybchenko /* 17206bc1977SAndrew Rybchenko * The EFX common code event queue module depends on the interrupt 17306bc1977SAndrew Rybchenko * module. Ensure that the interrupt module is always initialized 17406bc1977SAndrew Rybchenko * (even if interrupts are not used). Status memory is required 17506bc1977SAndrew Rybchenko * for Siena only and may be NULL for EF10. 17606bc1977SAndrew Rybchenko */ 17706bc1977SAndrew Rybchenko sfc_log_init(sa, "efx_intr_init"); 17806bc1977SAndrew Rybchenko rc = efx_intr_init(sa->nic, intr->type, NULL); 17906bc1977SAndrew Rybchenko if (rc != 0) 18006bc1977SAndrew Rybchenko goto fail_intr_init; 18106bc1977SAndrew Rybchenko 182c0802544SFerruh Yigit pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev); 18306bc1977SAndrew Rybchenko intr_handle = &pci_dev->intr_handle; 18406bc1977SAndrew Rybchenko 1853b809c27SAndrew Rybchenko if (intr->handler != NULL) { 1863b809c27SAndrew Rybchenko sfc_log_init(sa, "rte_intr_callback_register"); 1873b809c27SAndrew Rybchenko rc = rte_intr_callback_register(intr_handle, intr->handler, 1883b809c27SAndrew Rybchenko (void *)sa); 1893b809c27SAndrew Rybchenko if (rc != 0) { 1903b809c27SAndrew Rybchenko sfc_err(sa, 1913b809c27SAndrew Rybchenko "cannot register interrupt handler (rc=%d)", 1923b809c27SAndrew Rybchenko rc); 1933b809c27SAndrew Rybchenko /* 1943b809c27SAndrew Rybchenko * Convert error code from negative returned by RTE API 1953b809c27SAndrew Rybchenko * to positive used in the driver. 1963b809c27SAndrew Rybchenko */ 1973b809c27SAndrew Rybchenko rc = -rc; 1983b809c27SAndrew Rybchenko goto fail_rte_intr_cb_reg; 1993b809c27SAndrew Rybchenko } 2003b809c27SAndrew Rybchenko 2013b809c27SAndrew Rybchenko sfc_log_init(sa, "rte_intr_enable"); 2023b809c27SAndrew Rybchenko rc = rte_intr_enable(intr_handle); 2033b809c27SAndrew Rybchenko if (rc != 0) { 2043b809c27SAndrew Rybchenko sfc_err(sa, "cannot enable interrupts (rc=%d)", rc); 2053b809c27SAndrew Rybchenko /* 2063b809c27SAndrew Rybchenko * Convert error code from negative returned by RTE API 2073b809c27SAndrew Rybchenko * to positive used in the driver. 2083b809c27SAndrew Rybchenko */ 2093b809c27SAndrew Rybchenko rc = -rc; 2103b809c27SAndrew Rybchenko goto fail_rte_intr_enable; 2113b809c27SAndrew Rybchenko } 2123b809c27SAndrew Rybchenko 2133b809c27SAndrew Rybchenko sfc_log_init(sa, "efx_intr_enable"); 2143b809c27SAndrew Rybchenko efx_intr_enable(sa->nic); 2153b809c27SAndrew Rybchenko } 2163b809c27SAndrew Rybchenko 21706bc1977SAndrew Rybchenko sfc_log_init(sa, "done type=%u max_intr=%d nb_efd=%u vec=%p", 21806bc1977SAndrew Rybchenko intr_handle->type, intr_handle->max_intr, 21906bc1977SAndrew Rybchenko intr_handle->nb_efd, intr_handle->intr_vec); 22006bc1977SAndrew Rybchenko return 0; 22106bc1977SAndrew Rybchenko 2223b809c27SAndrew Rybchenko fail_rte_intr_enable: 2233b809c27SAndrew Rybchenko rte_intr_callback_unregister(intr_handle, intr->handler, (void *)sa); 2243b809c27SAndrew Rybchenko 2253b809c27SAndrew Rybchenko fail_rte_intr_cb_reg: 2263b809c27SAndrew Rybchenko efx_intr_fini(sa->nic); 2273b809c27SAndrew Rybchenko 22806bc1977SAndrew Rybchenko fail_intr_init: 22906bc1977SAndrew Rybchenko sfc_log_init(sa, "failed %d", rc); 23006bc1977SAndrew Rybchenko return rc; 23106bc1977SAndrew Rybchenko } 23206bc1977SAndrew Rybchenko 23306bc1977SAndrew Rybchenko void 23406bc1977SAndrew Rybchenko sfc_intr_stop(struct sfc_adapter *sa) 23506bc1977SAndrew Rybchenko { 2363b809c27SAndrew Rybchenko struct sfc_intr *intr = &sa->intr; 237c0802544SFerruh Yigit struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev); 2383b809c27SAndrew Rybchenko 23906bc1977SAndrew Rybchenko sfc_log_init(sa, "entry"); 24006bc1977SAndrew Rybchenko 2413b809c27SAndrew Rybchenko if (intr->handler != NULL) { 2423b809c27SAndrew Rybchenko struct rte_intr_handle *intr_handle; 2433b809c27SAndrew Rybchenko int rc; 2443b809c27SAndrew Rybchenko 2453b809c27SAndrew Rybchenko efx_intr_disable(sa->nic); 2463b809c27SAndrew Rybchenko 2473b809c27SAndrew Rybchenko intr_handle = &pci_dev->intr_handle; 2483b809c27SAndrew Rybchenko if (rte_intr_disable(intr_handle) != 0) 2493b809c27SAndrew Rybchenko sfc_err(sa, "cannot disable interrupts"); 2503b809c27SAndrew Rybchenko 2513b809c27SAndrew Rybchenko while ((rc = rte_intr_callback_unregister(intr_handle, 2523b809c27SAndrew Rybchenko intr->handler, (void *)sa)) == -EAGAIN) 2533b809c27SAndrew Rybchenko ; 2543b809c27SAndrew Rybchenko if (rc != 1) 2553b809c27SAndrew Rybchenko sfc_err(sa, 2563b809c27SAndrew Rybchenko "cannot unregister interrupt handler %d", 2573b809c27SAndrew Rybchenko rc); 2583b809c27SAndrew Rybchenko } 2593b809c27SAndrew Rybchenko 26006bc1977SAndrew Rybchenko efx_intr_fini(sa->nic); 26106bc1977SAndrew Rybchenko 26206bc1977SAndrew Rybchenko sfc_log_init(sa, "done"); 26306bc1977SAndrew Rybchenko } 26406bc1977SAndrew Rybchenko 26506bc1977SAndrew Rybchenko int 26652597396SAndrew Rybchenko sfc_intr_configure(struct sfc_adapter *sa) 26706bc1977SAndrew Rybchenko { 2683b809c27SAndrew Rybchenko struct sfc_intr *intr = &sa->intr; 2693b809c27SAndrew Rybchenko 27006bc1977SAndrew Rybchenko sfc_log_init(sa, "entry"); 27106bc1977SAndrew Rybchenko 2723b809c27SAndrew Rybchenko intr->handler = NULL; 2733b809c27SAndrew Rybchenko intr->lsc_intr = (sa->eth_dev->data->dev_conf.intr_conf.lsc != 0); 2743b809c27SAndrew Rybchenko if (!intr->lsc_intr) { 2753b809c27SAndrew Rybchenko sfc_info(sa, "LSC tracking using interrupts is disabled"); 2763b809c27SAndrew Rybchenko goto done; 2773b809c27SAndrew Rybchenko } 2783b809c27SAndrew Rybchenko 2793b809c27SAndrew Rybchenko switch (intr->type) { 2803b809c27SAndrew Rybchenko case EFX_INTR_MESSAGE: 2813b809c27SAndrew Rybchenko intr->handler = sfc_intr_message_handler; 2823b809c27SAndrew Rybchenko break; 2833b809c27SAndrew Rybchenko case EFX_INTR_LINE: 2843b809c27SAndrew Rybchenko intr->handler = sfc_intr_line_handler; 2853b809c27SAndrew Rybchenko break; 2863b809c27SAndrew Rybchenko case EFX_INTR_INVALID: 2873b809c27SAndrew Rybchenko sfc_warn(sa, "interrupts are not supported"); 2883b809c27SAndrew Rybchenko break; 2893b809c27SAndrew Rybchenko default: 2903b809c27SAndrew Rybchenko sfc_panic(sa, "unexpected EFX interrupt type %u\n", intr->type); 2913b809c27SAndrew Rybchenko break; 2923b809c27SAndrew Rybchenko } 2933b809c27SAndrew Rybchenko 2943b809c27SAndrew Rybchenko done: 29506bc1977SAndrew Rybchenko sfc_log_init(sa, "done"); 29606bc1977SAndrew Rybchenko return 0; 29706bc1977SAndrew Rybchenko } 29806bc1977SAndrew Rybchenko 29906bc1977SAndrew Rybchenko void 30052597396SAndrew Rybchenko sfc_intr_close(struct sfc_adapter *sa) 30106bc1977SAndrew Rybchenko { 30206bc1977SAndrew Rybchenko sfc_log_init(sa, "entry"); 30306bc1977SAndrew Rybchenko 30406bc1977SAndrew Rybchenko sfc_log_init(sa, "done"); 30506bc1977SAndrew Rybchenko } 30606bc1977SAndrew Rybchenko 30706bc1977SAndrew Rybchenko int 30806bc1977SAndrew Rybchenko sfc_intr_attach(struct sfc_adapter *sa) 30906bc1977SAndrew Rybchenko { 31006bc1977SAndrew Rybchenko struct sfc_intr *intr = &sa->intr; 311c0802544SFerruh Yigit struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(sa->eth_dev); 31206bc1977SAndrew Rybchenko 31306bc1977SAndrew Rybchenko sfc_log_init(sa, "entry"); 31406bc1977SAndrew Rybchenko 31506bc1977SAndrew Rybchenko switch (pci_dev->intr_handle.type) { 31606bc1977SAndrew Rybchenko #ifdef RTE_EXEC_ENV_LINUXAPP 317edd69f7cSAndrew Rybchenko case RTE_INTR_HANDLE_UIO_INTX: 31806bc1977SAndrew Rybchenko case RTE_INTR_HANDLE_VFIO_LEGACY: 31906bc1977SAndrew Rybchenko intr->type = EFX_INTR_LINE; 32006bc1977SAndrew Rybchenko break; 321edd69f7cSAndrew Rybchenko case RTE_INTR_HANDLE_UIO: 32206bc1977SAndrew Rybchenko case RTE_INTR_HANDLE_VFIO_MSI: 32306bc1977SAndrew Rybchenko case RTE_INTR_HANDLE_VFIO_MSIX: 32406bc1977SAndrew Rybchenko intr->type = EFX_INTR_MESSAGE; 32506bc1977SAndrew Rybchenko break; 32606bc1977SAndrew Rybchenko #endif 32706bc1977SAndrew Rybchenko default: 32806bc1977SAndrew Rybchenko intr->type = EFX_INTR_INVALID; 32906bc1977SAndrew Rybchenko break; 33006bc1977SAndrew Rybchenko } 33106bc1977SAndrew Rybchenko 33206bc1977SAndrew Rybchenko sfc_log_init(sa, "done"); 33306bc1977SAndrew Rybchenko return 0; 33406bc1977SAndrew Rybchenko } 33506bc1977SAndrew Rybchenko 33606bc1977SAndrew Rybchenko void 33706bc1977SAndrew Rybchenko sfc_intr_detach(struct sfc_adapter *sa) 33806bc1977SAndrew Rybchenko { 33906bc1977SAndrew Rybchenko sfc_log_init(sa, "entry"); 34006bc1977SAndrew Rybchenko 34106bc1977SAndrew Rybchenko sa->intr.type = EFX_INTR_INVALID; 34206bc1977SAndrew Rybchenko 34306bc1977SAndrew Rybchenko sfc_log_init(sa, "done"); 34406bc1977SAndrew Rybchenko } 345