net/sfc: add missing BSD license line and update year
[dpdk.git] / drivers / net / sfc / sfc.c
1 /*-
2  *   BSD LICENSE
3  *
4  * Copyright (c) 2016-2017 Solarflare Communications Inc.
5  * All rights reserved.
6  *
7  * This software was jointly developed between OKTET Labs (under contract
8  * for Solarflare) and Solarflare Communications, Inc.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright notice,
14  *    this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  *    this list of conditions and the following disclaimer in the documentation
17  *    and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 /* sysconf() */
33 #include <unistd.h>
34
35 #include <rte_errno.h>
36
37 #include "efx.h"
38
39 #include "sfc.h"
40 #include "sfc_log.h"
41 #include "sfc_ev.h"
42 #include "sfc_rx.h"
43 #include "sfc_tx.h"
44
45
46 int
47 sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
48               size_t len, int socket_id, efsys_mem_t *esmp)
49 {
50         const struct rte_memzone *mz;
51
52         sfc_log_init(sa, "name=%s id=%u len=%lu socket_id=%d",
53                      name, id, len, socket_id);
54
55         mz = rte_eth_dma_zone_reserve(sa->eth_dev, name, id, len,
56                                       sysconf(_SC_PAGESIZE), socket_id);
57         if (mz == NULL) {
58                 sfc_err(sa, "cannot reserve DMA zone for %s:%u %#x@%d: %s",
59                         name, (unsigned int)id, (unsigned int)len, socket_id,
60                         rte_strerror(rte_errno));
61                 return ENOMEM;
62         }
63
64         esmp->esm_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
65         if (esmp->esm_addr == RTE_BAD_PHYS_ADDR) {
66                 (void)rte_memzone_free(mz);
67                 return EFAULT;
68         }
69
70         esmp->esm_mz = mz;
71         esmp->esm_base = mz->addr;
72
73         return 0;
74 }
75
76 void
77 sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp)
78 {
79         int rc;
80
81         sfc_log_init(sa, "name=%s", esmp->esm_mz->name);
82
83         rc = rte_memzone_free(esmp->esm_mz);
84         if (rc != 0)
85                 sfc_err(sa, "rte_memzone_free(() failed: %d", rc);
86
87         memset(esmp, 0, sizeof(*esmp));
88 }
89
90 static uint32_t
91 sfc_phy_cap_from_link_speeds(uint32_t speeds)
92 {
93         uint32_t phy_caps = 0;
94
95         if (~speeds & ETH_LINK_SPEED_FIXED) {
96                 phy_caps |= (1 << EFX_PHY_CAP_AN);
97                 /*
98                  * If no speeds are specified in the mask, any supported
99                  * may be negotiated
100                  */
101                 if (speeds == ETH_LINK_SPEED_AUTONEG)
102                         phy_caps |=
103                                 (1 << EFX_PHY_CAP_1000FDX) |
104                                 (1 << EFX_PHY_CAP_10000FDX) |
105                                 (1 << EFX_PHY_CAP_40000FDX);
106         }
107         if (speeds & ETH_LINK_SPEED_1G)
108                 phy_caps |= (1 << EFX_PHY_CAP_1000FDX);
109         if (speeds & ETH_LINK_SPEED_10G)
110                 phy_caps |= (1 << EFX_PHY_CAP_10000FDX);
111         if (speeds & ETH_LINK_SPEED_40G)
112                 phy_caps |= (1 << EFX_PHY_CAP_40000FDX);
113
114         return phy_caps;
115 }
116
117 /*
118  * Check requested device level configuration.
119  * Receive and transmit configuration is checked in corresponding
120  * modules.
121  */
122 static int
123 sfc_check_conf(struct sfc_adapter *sa)
124 {
125         const struct rte_eth_conf *conf = &sa->eth_dev->data->dev_conf;
126         int rc = 0;
127
128         sa->port.phy_adv_cap =
129                 sfc_phy_cap_from_link_speeds(conf->link_speeds) &
130                 sa->port.phy_adv_cap_mask;
131         if ((sa->port.phy_adv_cap & ~(1 << EFX_PHY_CAP_AN)) == 0) {
132                 sfc_err(sa, "No link speeds from mask %#x are supported",
133                         conf->link_speeds);
134                 rc = EINVAL;
135         }
136
137         if (conf->lpbk_mode != 0) {
138                 sfc_err(sa, "Loopback not supported");
139                 rc = EINVAL;
140         }
141
142         if (conf->dcb_capability_en != 0) {
143                 sfc_err(sa, "Priority-based flow control not supported");
144                 rc = EINVAL;
145         }
146
147         if (conf->fdir_conf.mode != RTE_FDIR_MODE_NONE) {
148                 sfc_err(sa, "Flow Director not supported");
149                 rc = EINVAL;
150         }
151
152         if ((conf->intr_conf.lsc != 0) &&
153             (sa->intr.type != EFX_INTR_LINE) &&
154             (sa->intr.type != EFX_INTR_MESSAGE)) {
155                 sfc_err(sa, "Link status change interrupt not supported");
156                 rc = EINVAL;
157         }
158
159         if (conf->intr_conf.rxq != 0) {
160                 sfc_err(sa, "Receive queue interrupt not supported");
161                 rc = EINVAL;
162         }
163
164         return rc;
165 }
166
167 /*
168  * Find out maximum number of receive and transmit queues which could be
169  * advertised.
170  *
171  * NIC is kept initialized on success to allow other modules acquire
172  * defaults and capabilities.
173  */
174 static int
175 sfc_estimate_resource_limits(struct sfc_adapter *sa)
176 {
177         const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
178         efx_drv_limits_t limits;
179         int rc;
180         uint32_t evq_allocated;
181         uint32_t rxq_allocated;
182         uint32_t txq_allocated;
183
184         memset(&limits, 0, sizeof(limits));
185
186         /* Request at least one Rx and Tx queue */
187         limits.edl_min_rxq_count = 1;
188         limits.edl_min_txq_count = 1;
189         /* Management event queue plus event queue for each Tx and Rx queue */
190         limits.edl_min_evq_count =
191                 1 + limits.edl_min_rxq_count + limits.edl_min_txq_count;
192
193         /* Divide by number of functions to guarantee that all functions
194          * will get promised resources
195          */
196         /* FIXME Divide by number of functions (not 2) below */
197         limits.edl_max_evq_count = encp->enc_evq_limit / 2;
198         SFC_ASSERT(limits.edl_max_evq_count >= limits.edl_min_rxq_count);
199
200         /* Split equally between receive and transmit */
201         limits.edl_max_rxq_count =
202                 MIN(encp->enc_rxq_limit, (limits.edl_max_evq_count - 1) / 2);
203         SFC_ASSERT(limits.edl_max_rxq_count >= limits.edl_min_rxq_count);
204
205         limits.edl_max_txq_count =
206                 MIN(encp->enc_txq_limit,
207                     limits.edl_max_evq_count - 1 - limits.edl_max_rxq_count);
208
209         if (sa->tso)
210                 limits.edl_max_txq_count =
211                         MIN(limits.edl_max_txq_count,
212                             encp->enc_fw_assisted_tso_v2_n_contexts /
213                             encp->enc_hw_pf_count);
214
215         SFC_ASSERT(limits.edl_max_txq_count >= limits.edl_min_rxq_count);
216
217         /* Configure the minimum required resources needed for the
218          * driver to operate, and the maximum desired resources that the
219          * driver is capable of using.
220          */
221         efx_nic_set_drv_limits(sa->nic, &limits);
222
223         sfc_log_init(sa, "init nic");
224         rc = efx_nic_init(sa->nic);
225         if (rc != 0)
226                 goto fail_nic_init;
227
228         /* Find resource dimensions assigned by firmware to this function */
229         rc = efx_nic_get_vi_pool(sa->nic, &evq_allocated, &rxq_allocated,
230                                  &txq_allocated);
231         if (rc != 0)
232                 goto fail_get_vi_pool;
233
234         /* It still may allocate more than maximum, ensure limit */
235         evq_allocated = MIN(evq_allocated, limits.edl_max_evq_count);
236         rxq_allocated = MIN(rxq_allocated, limits.edl_max_rxq_count);
237         txq_allocated = MIN(txq_allocated, limits.edl_max_txq_count);
238
239         /* Subtract management EVQ not used for traffic */
240         SFC_ASSERT(evq_allocated > 0);
241         evq_allocated--;
242
243         /* Right now we use separate EVQ for Rx and Tx */
244         sa->rxq_max = MIN(rxq_allocated, evq_allocated / 2);
245         sa->txq_max = MIN(txq_allocated, evq_allocated - sa->rxq_max);
246
247         /* Keep NIC initialized */
248         return 0;
249
250 fail_get_vi_pool:
251 fail_nic_init:
252         efx_nic_fini(sa->nic);
253         return rc;
254 }
255
256 static int
257 sfc_set_drv_limits(struct sfc_adapter *sa)
258 {
259         const struct rte_eth_dev_data *data = sa->eth_dev->data;
260         efx_drv_limits_t lim;
261
262         memset(&lim, 0, sizeof(lim));
263
264         /* Limits are strict since take into account initial estimation */
265         lim.edl_min_evq_count = lim.edl_max_evq_count =
266                 1 + data->nb_rx_queues + data->nb_tx_queues;
267         lim.edl_min_rxq_count = lim.edl_max_rxq_count = data->nb_rx_queues;
268         lim.edl_min_txq_count = lim.edl_max_txq_count = data->nb_tx_queues;
269
270         return efx_nic_set_drv_limits(sa->nic, &lim);
271 }
272
273 int
274 sfc_start(struct sfc_adapter *sa)
275 {
276         int rc;
277
278         sfc_log_init(sa, "entry");
279
280         SFC_ASSERT(sfc_adapter_is_locked(sa));
281
282         switch (sa->state) {
283         case SFC_ADAPTER_CONFIGURED:
284                 break;
285         case SFC_ADAPTER_STARTED:
286                 sfc_info(sa, "already started");
287                 return 0;
288         default:
289                 rc = EINVAL;
290                 goto fail_bad_state;
291         }
292
293         sa->state = SFC_ADAPTER_STARTING;
294
295         sfc_log_init(sa, "set resource limits");
296         rc = sfc_set_drv_limits(sa);
297         if (rc != 0)
298                 goto fail_set_drv_limits;
299
300         sfc_log_init(sa, "init nic");
301         rc = efx_nic_init(sa->nic);
302         if (rc != 0)
303                 goto fail_nic_init;
304
305         rc = sfc_intr_start(sa);
306         if (rc != 0)
307                 goto fail_intr_start;
308
309         rc = sfc_ev_start(sa);
310         if (rc != 0)
311                 goto fail_ev_start;
312
313         rc = sfc_port_start(sa);
314         if (rc != 0)
315                 goto fail_port_start;
316
317         rc = sfc_rx_start(sa);
318         if (rc != 0)
319                 goto fail_rx_start;
320
321         rc = sfc_tx_start(sa);
322         if (rc != 0)
323                 goto fail_tx_start;
324
325         rc = sfc_flow_start(sa);
326         if (rc != 0)
327                 goto fail_flows_insert;
328
329         sa->state = SFC_ADAPTER_STARTED;
330         sfc_log_init(sa, "done");
331         return 0;
332
333 fail_flows_insert:
334         sfc_tx_stop(sa);
335
336 fail_tx_start:
337         sfc_rx_stop(sa);
338
339 fail_rx_start:
340         sfc_port_stop(sa);
341
342 fail_port_start:
343         sfc_ev_stop(sa);
344
345 fail_ev_start:
346         sfc_intr_stop(sa);
347
348 fail_intr_start:
349         efx_nic_fini(sa->nic);
350
351 fail_nic_init:
352 fail_set_drv_limits:
353         sa->state = SFC_ADAPTER_CONFIGURED;
354 fail_bad_state:
355         sfc_log_init(sa, "failed %d", rc);
356         return rc;
357 }
358
359 void
360 sfc_stop(struct sfc_adapter *sa)
361 {
362         sfc_log_init(sa, "entry");
363
364         SFC_ASSERT(sfc_adapter_is_locked(sa));
365
366         switch (sa->state) {
367         case SFC_ADAPTER_STARTED:
368                 break;
369         case SFC_ADAPTER_CONFIGURED:
370                 sfc_info(sa, "already stopped");
371                 return;
372         default:
373                 sfc_err(sa, "stop in unexpected state %u", sa->state);
374                 SFC_ASSERT(B_FALSE);
375                 return;
376         }
377
378         sa->state = SFC_ADAPTER_STOPPING;
379
380         sfc_flow_stop(sa);
381         sfc_tx_stop(sa);
382         sfc_rx_stop(sa);
383         sfc_port_stop(sa);
384         sfc_ev_stop(sa);
385         sfc_intr_stop(sa);
386         efx_nic_fini(sa->nic);
387
388         sa->state = SFC_ADAPTER_CONFIGURED;
389         sfc_log_init(sa, "done");
390 }
391
392 int
393 sfc_configure(struct sfc_adapter *sa)
394 {
395         int rc;
396
397         sfc_log_init(sa, "entry");
398
399         SFC_ASSERT(sfc_adapter_is_locked(sa));
400
401         SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
402         sa->state = SFC_ADAPTER_CONFIGURING;
403
404         rc = sfc_check_conf(sa);
405         if (rc != 0)
406                 goto fail_check_conf;
407
408         rc = sfc_intr_init(sa);
409         if (rc != 0)
410                 goto fail_intr_init;
411
412         rc = sfc_ev_init(sa);
413         if (rc != 0)
414                 goto fail_ev_init;
415
416         rc = sfc_port_init(sa);
417         if (rc != 0)
418                 goto fail_port_init;
419
420         rc = sfc_rx_init(sa);
421         if (rc != 0)
422                 goto fail_rx_init;
423
424         rc = sfc_tx_init(sa);
425         if (rc != 0)
426                 goto fail_tx_init;
427
428         sa->state = SFC_ADAPTER_CONFIGURED;
429         sfc_log_init(sa, "done");
430         return 0;
431
432 fail_tx_init:
433         sfc_rx_fini(sa);
434
435 fail_rx_init:
436         sfc_port_fini(sa);
437
438 fail_port_init:
439         sfc_ev_fini(sa);
440
441 fail_ev_init:
442         sfc_intr_fini(sa);
443
444 fail_intr_init:
445 fail_check_conf:
446         sa->state = SFC_ADAPTER_INITIALIZED;
447         sfc_log_init(sa, "failed %d", rc);
448         return rc;
449 }
450
451 void
452 sfc_close(struct sfc_adapter *sa)
453 {
454         sfc_log_init(sa, "entry");
455
456         SFC_ASSERT(sfc_adapter_is_locked(sa));
457
458         SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
459         sa->state = SFC_ADAPTER_CLOSING;
460
461         sfc_tx_fini(sa);
462         sfc_rx_fini(sa);
463         sfc_port_fini(sa);
464         sfc_ev_fini(sa);
465         sfc_intr_fini(sa);
466
467         sa->state = SFC_ADAPTER_INITIALIZED;
468         sfc_log_init(sa, "done");
469 }
470
471 static int
472 sfc_mem_bar_init(struct sfc_adapter *sa)
473 {
474         struct rte_eth_dev *eth_dev = sa->eth_dev;
475         struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(eth_dev);
476         efsys_bar_t *ebp = &sa->mem_bar;
477         unsigned int i;
478         struct rte_mem_resource *res;
479
480         for (i = 0; i < RTE_DIM(pci_dev->mem_resource); i++) {
481                 res = &pci_dev->mem_resource[i];
482                 if ((res->len != 0) && (res->phys_addr != 0)) {
483                         /* Found first memory BAR */
484                         SFC_BAR_LOCK_INIT(ebp, eth_dev->data->name);
485                         ebp->esb_rid = i;
486                         ebp->esb_dev = pci_dev;
487                         ebp->esb_base = res->addr;
488                         return 0;
489                 }
490         }
491
492         return EFAULT;
493 }
494
495 static void
496 sfc_mem_bar_fini(struct sfc_adapter *sa)
497 {
498         efsys_bar_t *ebp = &sa->mem_bar;
499
500         SFC_BAR_LOCK_DESTROY(ebp);
501         memset(ebp, 0, sizeof(*ebp));
502 }
503
504 #if EFSYS_OPT_RX_SCALE
505 /*
506  * A fixed RSS key which has a property of being symmetric
507  * (symmetrical flows are distributed to the same CPU)
508  * and also known to give a uniform distribution
509  * (a good distribution of traffic between different CPUs)
510  */
511 static const uint8_t default_rss_key[SFC_RSS_KEY_SIZE] = {
512         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
513         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
514         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
515         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
516         0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a, 0x6d, 0x5a,
517 };
518 #endif
519
520 static int
521 sfc_set_rss_defaults(struct sfc_adapter *sa)
522 {
523 #if EFSYS_OPT_RX_SCALE
524         int rc;
525
526         rc = efx_intr_init(sa->nic, sa->intr.type, NULL);
527         if (rc != 0)
528                 goto fail_intr_init;
529
530         rc = efx_ev_init(sa->nic);
531         if (rc != 0)
532                 goto fail_ev_init;
533
534         rc = efx_rx_init(sa->nic);
535         if (rc != 0)
536                 goto fail_rx_init;
537
538         rc = efx_rx_scale_support_get(sa->nic, &sa->rss_support);
539         if (rc != 0)
540                 goto fail_scale_support_get;
541
542         rc = efx_rx_hash_support_get(sa->nic, &sa->hash_support);
543         if (rc != 0)
544                 goto fail_hash_support_get;
545
546         efx_rx_fini(sa->nic);
547         efx_ev_fini(sa->nic);
548         efx_intr_fini(sa->nic);
549
550         sa->rss_hash_types = sfc_rte_to_efx_hash_type(SFC_RSS_OFFLOADS);
551
552         rte_memcpy(sa->rss_key, default_rss_key, sizeof(sa->rss_key));
553
554         return 0;
555
556 fail_hash_support_get:
557 fail_scale_support_get:
558 fail_rx_init:
559         efx_ev_fini(sa->nic);
560
561 fail_ev_init:
562         efx_intr_fini(sa->nic);
563
564 fail_intr_init:
565         return rc;
566 #else
567         return 0;
568 #endif
569 }
570
571 int
572 sfc_attach(struct sfc_adapter *sa)
573 {
574         struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(sa->eth_dev);
575         const efx_nic_cfg_t *encp;
576         efx_nic_t *enp;
577         int rc;
578
579         sfc_log_init(sa, "entry");
580
581         SFC_ASSERT(sfc_adapter_is_locked(sa));
582
583         sa->socket_id = rte_socket_id();
584
585         sfc_log_init(sa, "init mem bar");
586         rc = sfc_mem_bar_init(sa);
587         if (rc != 0)
588                 goto fail_mem_bar_init;
589
590         sfc_log_init(sa, "get family");
591         rc = efx_family(pci_dev->id.vendor_id, pci_dev->id.device_id,
592                         &sa->family);
593         if (rc != 0)
594                 goto fail_family;
595         sfc_log_init(sa, "family is %u", sa->family);
596
597         sfc_log_init(sa, "create nic");
598         rte_spinlock_init(&sa->nic_lock);
599         rc = efx_nic_create(sa->family, (efsys_identifier_t *)sa,
600                             &sa->mem_bar, &sa->nic_lock, &enp);
601         if (rc != 0)
602                 goto fail_nic_create;
603         sa->nic = enp;
604
605         rc = sfc_mcdi_init(sa);
606         if (rc != 0)
607                 goto fail_mcdi_init;
608
609         sfc_log_init(sa, "probe nic");
610         rc = efx_nic_probe(enp);
611         if (rc != 0)
612                 goto fail_nic_probe;
613
614         efx_mcdi_new_epoch(enp);
615
616         sfc_log_init(sa, "reset nic");
617         rc = efx_nic_reset(enp);
618         if (rc != 0)
619                 goto fail_nic_reset;
620
621         encp = efx_nic_cfg_get(sa->nic);
622
623         sa->tso = encp->enc_fw_assisted_tso_v2_enabled;
624         if (!sa->tso)
625                 sfc_warn(sa, "TSO support isn't available on this adapter");
626
627         sfc_log_init(sa, "estimate resource limits");
628         rc = sfc_estimate_resource_limits(sa);
629         if (rc != 0)
630                 goto fail_estimate_rsrc_limits;
631
632         sa->txq_max_entries = encp->enc_txq_max_ndescs;
633         SFC_ASSERT(rte_is_power_of_2(sa->txq_max_entries));
634
635         rc = sfc_intr_attach(sa);
636         if (rc != 0)
637                 goto fail_intr_attach;
638
639         efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM,
640                             &sa->port.phy_adv_cap_mask);
641
642         rc = sfc_set_rss_defaults(sa);
643         if (rc != 0)
644                 goto fail_set_rss_defaults;
645
646         rc = sfc_filter_attach(sa);
647         if (rc != 0)
648                 goto fail_filter_attach;
649
650         sfc_log_init(sa, "fini nic");
651         efx_nic_fini(enp);
652
653         sfc_flow_init(sa);
654
655         sa->state = SFC_ADAPTER_INITIALIZED;
656
657         sfc_log_init(sa, "done");
658         return 0;
659
660 fail_filter_attach:
661 fail_set_rss_defaults:
662         sfc_intr_detach(sa);
663
664 fail_intr_attach:
665         efx_nic_fini(sa->nic);
666
667 fail_estimate_rsrc_limits:
668 fail_nic_reset:
669         sfc_log_init(sa, "unprobe nic");
670         efx_nic_unprobe(enp);
671
672 fail_nic_probe:
673         sfc_mcdi_fini(sa);
674
675 fail_mcdi_init:
676         sfc_log_init(sa, "destroy nic");
677         sa->nic = NULL;
678         efx_nic_destroy(enp);
679
680 fail_nic_create:
681 fail_family:
682         sfc_mem_bar_fini(sa);
683
684 fail_mem_bar_init:
685         sfc_log_init(sa, "failed %d", rc);
686         return rc;
687 }
688
689 void
690 sfc_detach(struct sfc_adapter *sa)
691 {
692         efx_nic_t *enp = sa->nic;
693
694         sfc_log_init(sa, "entry");
695
696         SFC_ASSERT(sfc_adapter_is_locked(sa));
697
698         sfc_filter_detach(sa);
699
700         sfc_intr_detach(sa);
701
702         sfc_log_init(sa, "unprobe nic");
703         efx_nic_unprobe(enp);
704
705         sfc_mcdi_fini(sa);
706
707         sfc_log_init(sa, "destroy nic");
708         sa->nic = NULL;
709         efx_nic_destroy(enp);
710
711         sfc_mem_bar_fini(sa);
712
713         sfc_flow_fini(sa);
714         sa->state = SFC_ADAPTER_UNINITIALIZED;
715 }