net/sfc: fix MAC stats update for stopped device
[dpdk.git] / drivers / net / sfc / sfc_port.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2021 Xilinx, Inc.
4  * Copyright(c) 2016-2019 Solarflare Communications Inc.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9
10 #include "efx.h"
11
12 #include "sfc.h"
13 #include "sfc_debug.h"
14 #include "sfc_log.h"
15 #include "sfc_kvargs.h"
16
17 /** Default MAC statistics update period is 1 second */
18 #define SFC_MAC_STATS_UPDATE_PERIOD_MS_DEF      MS_PER_S
19
20 /** The number of microseconds to sleep on attempt to get statistics update */
21 #define SFC_MAC_STATS_UPDATE_RETRY_INTERVAL_US  10
22
23 /** The number of attempts to await arrival of freshly generated statistics */
24 #define SFC_MAC_STATS_UPDATE_NB_ATTEMPTS        50
25
26 /**
27  * Update MAC statistics in the buffer.
28  *
29  * @param       sa              Adapter
30  * @param       force_upload    Flag to upload MAC stats in any case
31  *
32  * @return Status code
33  * @retval      0       Success
34  * @retval      EAGAIN  Try again
35  * @retval      ENOMEM  Memory allocation failure
36  */
37 int
38 sfc_port_update_mac_stats(struct sfc_adapter *sa, boolean_t force_upload)
39 {
40         struct sfc_port *port = &sa->port;
41         efsys_mem_t *esmp = &port->mac_stats_dma_mem;
42         uint32_t *genp = NULL;
43         uint32_t gen_old;
44         unsigned int nb_attempts = 0;
45         int rc;
46
47         SFC_ASSERT(sfc_adapter_is_locked(sa));
48
49         if (sa->state != SFC_ADAPTER_STARTED)
50                 return 0;
51
52         /*
53          * If periodic statistics DMA'ing is off or if not supported,
54          * make a manual request and keep an eye on timer if need be
55          */
56         if (!port->mac_stats_periodic_dma_supported ||
57             (port->mac_stats_update_period_ms == 0) || force_upload) {
58                 if (port->mac_stats_update_period_ms != 0) {
59                         uint64_t timestamp = sfc_get_system_msecs();
60
61                         if ((timestamp -
62                              port->mac_stats_last_request_timestamp) <
63                             port->mac_stats_update_period_ms)
64                                 return 0;
65
66                         port->mac_stats_last_request_timestamp = timestamp;
67                 }
68
69                 rc = efx_mac_stats_upload(sa->nic, esmp);
70                 if (rc != 0)
71                         return rc;
72
73                 genp = &port->mac_stats_update_generation;
74                 gen_old = *genp;
75         }
76
77         do {
78                 if (nb_attempts > 0)
79                         rte_delay_us(SFC_MAC_STATS_UPDATE_RETRY_INTERVAL_US);
80
81                 rc = efx_mac_stats_update(sa->nic, esmp,
82                                           port->mac_stats_buf, genp);
83                 if (rc != 0)
84                         return rc;
85
86         } while ((genp != NULL) && (*genp == gen_old) &&
87                  (++nb_attempts < SFC_MAC_STATS_UPDATE_NB_ATTEMPTS));
88
89         return 0;
90 }
91
92 static void
93 sfc_port_reset_sw_stats(struct sfc_adapter *sa)
94 {
95         struct sfc_port *port = &sa->port;
96
97         /*
98          * Reset diff stats explicitly since check which does not allow
99          * the statistics to grow backward could deny it.
100          */
101         port->ipackets = 0;
102 }
103
104 int
105 sfc_port_reset_mac_stats(struct sfc_adapter *sa)
106 {
107         int rc;
108
109         SFC_ASSERT(sfc_adapter_is_locked(sa));
110
111         rc = efx_mac_stats_clear(sa->nic);
112         if (rc == 0)
113                 sfc_port_reset_sw_stats(sa);
114
115         return rc;
116 }
117
118 static int
119 sfc_port_init_dev_link(struct sfc_adapter *sa)
120 {
121         struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
122         int rc;
123         efx_link_mode_t link_mode;
124         struct rte_eth_link current_link;
125
126         rc = efx_port_poll(sa->nic, &link_mode);
127         if (rc != 0)
128                 return rc;
129
130         sfc_port_link_mode_to_info(link_mode, &current_link);
131
132         EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
133         rte_atomic64_set((rte_atomic64_t *)dev_link,
134                          *(uint64_t *)&current_link);
135
136         return 0;
137 }
138
139 #if EFSYS_OPT_LOOPBACK
140
141 static efx_link_mode_t
142 sfc_port_phy_caps_to_max_link_speed(uint32_t phy_caps)
143 {
144         if (phy_caps & (1u << EFX_PHY_CAP_100000FDX))
145                 return EFX_LINK_100000FDX;
146         if (phy_caps & (1u << EFX_PHY_CAP_50000FDX))
147                 return EFX_LINK_50000FDX;
148         if (phy_caps & (1u << EFX_PHY_CAP_40000FDX))
149                 return EFX_LINK_40000FDX;
150         if (phy_caps & (1u << EFX_PHY_CAP_25000FDX))
151                 return EFX_LINK_25000FDX;
152         if (phy_caps & (1u << EFX_PHY_CAP_10000FDX))
153                 return EFX_LINK_10000FDX;
154         if (phy_caps & (1u << EFX_PHY_CAP_1000FDX))
155                 return EFX_LINK_1000FDX;
156         return EFX_LINK_UNKNOWN;
157 }
158
159 #endif
160
161 static void
162 sfc_port_fill_mac_stats_info(struct sfc_adapter *sa)
163 {
164         unsigned int mac_stats_nb_supported = 0;
165         struct sfc_port *port = &sa->port;
166         unsigned int stat_idx;
167
168         efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask,
169                                sizeof(port->mac_stats_mask));
170
171         for (stat_idx = 0; stat_idx < EFX_MAC_NSTATS; ++stat_idx) {
172                 if (!EFX_MAC_STAT_SUPPORTED(port->mac_stats_mask, stat_idx))
173                         continue;
174
175                 port->mac_stats_by_id[mac_stats_nb_supported] = stat_idx;
176                 mac_stats_nb_supported++;
177         }
178
179         port->mac_stats_nb_supported = mac_stats_nb_supported;
180 }
181
182 int
183 sfc_port_start(struct sfc_adapter *sa)
184 {
185         struct sfc_port *port = &sa->port;
186         int rc;
187         uint32_t phy_adv_cap;
188         const uint32_t phy_pause_caps =
189                 ((1u << EFX_PHY_CAP_PAUSE) | (1u << EFX_PHY_CAP_ASYM));
190
191         sfc_log_init(sa, "entry");
192
193         sfc_log_init(sa, "init filters");
194         rc = efx_filter_init(sa->nic);
195         if (rc != 0)
196                 goto fail_filter_init;
197
198         sfc_log_init(sa, "init port");
199         rc = efx_port_init(sa->nic);
200         if (rc != 0)
201                 goto fail_port_init;
202
203 #if EFSYS_OPT_LOOPBACK
204         if (sa->eth_dev->data->dev_conf.lpbk_mode != 0) {
205                 efx_link_mode_t link_mode;
206
207                 link_mode =
208                         sfc_port_phy_caps_to_max_link_speed(port->phy_adv_cap);
209                 sfc_log_init(sa, "set loopback link_mode=%u type=%u", link_mode,
210                              sa->eth_dev->data->dev_conf.lpbk_mode);
211                 rc = efx_port_loopback_set(sa->nic, link_mode,
212                         sa->eth_dev->data->dev_conf.lpbk_mode);
213                 if (rc != 0)
214                         goto fail_loopback_set;
215         }
216 #endif
217
218         sfc_log_init(sa, "set flow control to %#x autoneg=%u",
219                      port->flow_ctrl, port->flow_ctrl_autoneg);
220         rc = efx_mac_fcntl_set(sa->nic, port->flow_ctrl,
221                                port->flow_ctrl_autoneg);
222         if (rc != 0)
223                 goto fail_mac_fcntl_set;
224
225         /* Preserve pause capabilities set by above efx_mac_fcntl_set()  */
226         efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT, &phy_adv_cap);
227         SFC_ASSERT((port->phy_adv_cap & phy_pause_caps) == 0);
228         phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps);
229
230         /*
231          * No controls for FEC yet. Use default FEC mode.
232          * I.e. advertise everything supported (*_FEC=1), but do not request
233          * anything explicitly (*_FEC_REQUESTED=0).
234          */
235         phy_adv_cap |= port->phy_adv_cap_mask &
236                 (1u << EFX_PHY_CAP_BASER_FEC |
237                  1u << EFX_PHY_CAP_RS_FEC |
238                  1u << EFX_PHY_CAP_25G_BASER_FEC);
239
240         sfc_log_init(sa, "set phy adv caps to %#x", phy_adv_cap);
241         rc = efx_phy_adv_cap_set(sa->nic, phy_adv_cap);
242         if (rc != 0)
243                 goto fail_phy_adv_cap_set;
244
245         sfc_log_init(sa, "set MAC PDU %u", (unsigned int)port->pdu);
246         rc = efx_mac_pdu_set(sa->nic, port->pdu);
247         if (rc != 0)
248                 goto fail_mac_pdu_set;
249
250         if (!sfc_sa2shared(sa)->isolated) {
251                 struct rte_ether_addr *addr = &port->default_mac_addr;
252
253                 sfc_log_init(sa, "set MAC address");
254                 rc = efx_mac_addr_set(sa->nic, addr->addr_bytes);
255                 if (rc != 0)
256                         goto fail_mac_addr_set;
257
258                 sfc_log_init(sa, "set MAC filters");
259                 port->promisc = (sa->eth_dev->data->promiscuous != 0) ?
260                                 B_TRUE : B_FALSE;
261                 port->allmulti = (sa->eth_dev->data->all_multicast != 0) ?
262                                  B_TRUE : B_FALSE;
263                 rc = sfc_set_rx_mode_unchecked(sa);
264                 if (rc != 0)
265                         goto fail_mac_filter_set;
266
267                 sfc_log_init(sa, "set multicast address list");
268                 rc = efx_mac_multicast_list_set(sa->nic, port->mcast_addrs,
269                                                 port->nb_mcast_addrs);
270                 if (rc != 0)
271                         goto fail_mcast_address_list_set;
272         }
273
274         if (port->mac_stats_reset_pending) {
275                 rc = sfc_port_reset_mac_stats(sa);
276                 if (rc != 0)
277                         sfc_err(sa, "statistics reset failed (requested "
278                                     "before the port was started)");
279
280                 port->mac_stats_reset_pending = B_FALSE;
281         }
282
283         sfc_port_fill_mac_stats_info(sa);
284
285         port->mac_stats_update_generation = 0;
286
287         if (port->mac_stats_update_period_ms != 0) {
288                 /*
289                  * Update MAC stats using periodic DMA;
290                  * any positive update interval different from
291                  * 1000 ms can be set only on SFN8xxx provided
292                  * that FW version is 6.2.1.1033 or higher
293                  */
294                 sfc_log_init(sa, "request MAC stats DMA'ing");
295                 rc = efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
296                                             port->mac_stats_update_period_ms,
297                                             B_FALSE);
298                 if (rc == 0) {
299                         port->mac_stats_periodic_dma_supported = B_TRUE;
300                 } else if (rc == EOPNOTSUPP) {
301                         port->mac_stats_periodic_dma_supported = B_FALSE;
302                         port->mac_stats_last_request_timestamp = 0;
303                 } else {
304                         goto fail_mac_stats_periodic;
305                 }
306         }
307
308         if ((port->mac_stats_update_period_ms != 0) &&
309             port->mac_stats_periodic_dma_supported) {
310                 /*
311                  * Request an explicit MAC stats upload immediately to
312                  * preclude bogus figures readback if the user decides
313                  * to read stats before periodic DMA is really started
314                  */
315                 rc = efx_mac_stats_upload(sa->nic, &port->mac_stats_dma_mem);
316                 if (rc != 0)
317                         goto fail_mac_stats_upload;
318         }
319
320         sfc_log_init(sa, "disable MAC drain");
321         rc = efx_mac_drain(sa->nic, B_FALSE);
322         if (rc != 0)
323                 goto fail_mac_drain;
324
325         /* Synchronize link status knowledge */
326         rc = sfc_port_init_dev_link(sa);
327         if (rc != 0)
328                 goto fail_port_init_dev_link;
329
330         sfc_log_init(sa, "done");
331         return 0;
332
333 fail_port_init_dev_link:
334         (void)efx_mac_drain(sa->nic, B_TRUE);
335
336 fail_mac_drain:
337 fail_mac_stats_upload:
338         (void)efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
339                                      0, B_FALSE);
340
341 fail_mac_stats_periodic:
342 fail_mcast_address_list_set:
343 fail_mac_filter_set:
344 fail_mac_addr_set:
345 fail_mac_pdu_set:
346 fail_phy_adv_cap_set:
347 fail_mac_fcntl_set:
348 #if EFSYS_OPT_LOOPBACK
349 fail_loopback_set:
350 #endif
351         efx_port_fini(sa->nic);
352
353 fail_port_init:
354         efx_filter_fini(sa->nic);
355
356 fail_filter_init:
357         sfc_log_init(sa, "failed %d", rc);
358         return rc;
359 }
360
361 void
362 sfc_port_stop(struct sfc_adapter *sa)
363 {
364         sfc_log_init(sa, "entry");
365
366         efx_mac_drain(sa->nic, B_TRUE);
367
368         (void)efx_mac_stats_periodic(sa->nic, &sa->port.mac_stats_dma_mem,
369                                      0, B_FALSE);
370
371         sfc_port_update_mac_stats(sa, B_TRUE);
372
373         efx_port_fini(sa->nic);
374         efx_filter_fini(sa->nic);
375
376         sfc_log_init(sa, "done");
377 }
378
379 int
380 sfc_port_configure(struct sfc_adapter *sa)
381 {
382         const struct rte_eth_dev_data *dev_data = sa->eth_dev->data;
383         struct sfc_port *port = &sa->port;
384         const struct rte_eth_rxmode *rxmode = &dev_data->dev_conf.rxmode;
385
386         sfc_log_init(sa, "entry");
387
388         if (rxmode->offloads & DEV_RX_OFFLOAD_JUMBO_FRAME)
389                 port->pdu = rxmode->max_rx_pkt_len;
390         else
391                 port->pdu = EFX_MAC_PDU(dev_data->mtu);
392
393         return 0;
394 }
395
396 void
397 sfc_port_close(struct sfc_adapter *sa)
398 {
399         sfc_log_init(sa, "entry");
400 }
401
402 int
403 sfc_port_attach(struct sfc_adapter *sa)
404 {
405         struct sfc_port *port = &sa->port;
406         const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
407         const struct rte_ether_addr *from;
408         uint32_t mac_nstats;
409         size_t mac_stats_size;
410         long kvarg_stats_update_period_ms;
411         int rc;
412
413         sfc_log_init(sa, "entry");
414
415         efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &port->phy_adv_cap_mask);
416
417         /* Enable flow control by default */
418         port->flow_ctrl = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
419         port->flow_ctrl_autoneg = B_TRUE;
420
421         RTE_BUILD_BUG_ON(sizeof(encp->enc_mac_addr) != sizeof(*from));
422         from = (const struct rte_ether_addr *)(encp->enc_mac_addr);
423         rte_ether_addr_copy(from, &port->default_mac_addr);
424
425         port->max_mcast_addrs = EFX_MAC_MULTICAST_LIST_MAX;
426         port->nb_mcast_addrs = 0;
427         port->mcast_addrs = rte_calloc_socket("mcast_addr_list_buf",
428                                               port->max_mcast_addrs,
429                                               EFX_MAC_ADDR_LEN, 0,
430                                               sa->socket_id);
431         if (port->mcast_addrs == NULL) {
432                 rc = ENOMEM;
433                 goto fail_mcast_addr_list_buf_alloc;
434         }
435
436         rc = ENOMEM;
437         port->mac_stats_buf = rte_calloc_socket("mac_stats_buf", EFX_MAC_NSTATS,
438                                                 sizeof(uint64_t), 0,
439                                                 sa->socket_id);
440         if (port->mac_stats_buf == NULL)
441                 goto fail_mac_stats_buf_alloc;
442
443         mac_nstats = efx_nic_cfg_get(sa->nic)->enc_mac_stats_nstats;
444         mac_stats_size = RTE_ALIGN(mac_nstats * sizeof(uint64_t), EFX_BUF_SIZE);
445         rc = sfc_dma_alloc(sa, "mac_stats", 0, mac_stats_size,
446                            sa->socket_id, &port->mac_stats_dma_mem);
447         if (rc != 0)
448                 goto fail_mac_stats_dma_alloc;
449
450         port->mac_stats_reset_pending = B_FALSE;
451
452         kvarg_stats_update_period_ms = SFC_MAC_STATS_UPDATE_PERIOD_MS_DEF;
453
454         rc = sfc_kvargs_process(sa, SFC_KVARG_STATS_UPDATE_PERIOD_MS,
455                                 sfc_kvarg_long_handler,
456                                 &kvarg_stats_update_period_ms);
457         if ((rc == 0) &&
458             ((kvarg_stats_update_period_ms < 0) ||
459              (kvarg_stats_update_period_ms > UINT16_MAX))) {
460                 sfc_err(sa, "wrong '" SFC_KVARG_STATS_UPDATE_PERIOD_MS "' "
461                             "was set (%ld);", kvarg_stats_update_period_ms);
462                 sfc_err(sa, "it must not be less than 0 "
463                             "or greater than %" PRIu16, UINT16_MAX);
464                 rc = EINVAL;
465                 goto fail_kvarg_stats_update_period_ms;
466         } else if (rc != 0) {
467                 goto fail_kvarg_stats_update_period_ms;
468         }
469
470         port->mac_stats_update_period_ms = kvarg_stats_update_period_ms;
471
472         sfc_log_init(sa, "done");
473         return 0;
474
475 fail_kvarg_stats_update_period_ms:
476         sfc_dma_free(sa, &port->mac_stats_dma_mem);
477
478 fail_mac_stats_dma_alloc:
479         rte_free(port->mac_stats_buf);
480
481 fail_mac_stats_buf_alloc:
482         rte_free(port->mcast_addrs);
483
484 fail_mcast_addr_list_buf_alloc:
485         sfc_log_init(sa, "failed %d", rc);
486         return rc;
487 }
488
489 void
490 sfc_port_detach(struct sfc_adapter *sa)
491 {
492         struct sfc_port *port = &sa->port;
493
494         sfc_log_init(sa, "entry");
495
496         sfc_dma_free(sa, &port->mac_stats_dma_mem);
497         rte_free(port->mac_stats_buf);
498
499         rte_free(port->mcast_addrs);
500
501         sfc_log_init(sa, "done");
502 }
503
504 static boolean_t
505 sfc_get_requested_all_ucast(struct sfc_port *port)
506 {
507         return port->promisc;
508 }
509
510 static boolean_t
511 sfc_get_requested_all_mcast(struct sfc_port *port)
512 {
513         return port->promisc || port->allmulti;
514 }
515
516 int
517 sfc_set_rx_mode_unchecked(struct sfc_adapter *sa)
518 {
519         struct sfc_port *port = &sa->port;
520         boolean_t requested_all_ucast = sfc_get_requested_all_ucast(port);
521         boolean_t requested_all_mcast = sfc_get_requested_all_mcast(port);
522         int rc;
523
524         rc = efx_mac_filter_set(sa->nic, requested_all_ucast, B_TRUE,
525                                 requested_all_mcast, B_TRUE);
526         if (rc != 0)
527                 return rc;
528
529         return 0;
530 }
531
532 int
533 sfc_set_rx_mode(struct sfc_adapter *sa)
534 {
535         struct sfc_port *port = &sa->port;
536         boolean_t old_all_ucast;
537         boolean_t old_all_mcast;
538         boolean_t requested_all_ucast = sfc_get_requested_all_ucast(port);
539         boolean_t requested_all_mcast = sfc_get_requested_all_mcast(port);
540         boolean_t actual_all_ucast;
541         boolean_t actual_all_mcast;
542         int rc;
543
544         efx_mac_filter_get_all_ucast_mcast(sa->nic, &old_all_ucast,
545                                            &old_all_mcast);
546
547         rc = sfc_set_rx_mode_unchecked(sa);
548         if (rc != 0)
549                 return rc;
550
551         efx_mac_filter_get_all_ucast_mcast(sa->nic, &actual_all_ucast,
552                                            &actual_all_mcast);
553
554         if (actual_all_ucast != requested_all_ucast ||
555             actual_all_mcast != requested_all_mcast) {
556                 /*
557                  * MAC filter set succeeded but not all requested modes
558                  * were applied. The rollback is necessary to bring back the
559                  * consistent old state.
560                  */
561                 (void)efx_mac_filter_set(sa->nic, old_all_ucast, B_TRUE,
562                                          old_all_mcast, B_TRUE);
563
564                 return EPERM;
565         }
566
567         return 0;
568 }
569
570 void
571 sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
572                            struct rte_eth_link *link_info)
573 {
574         SFC_ASSERT(link_mode < EFX_LINK_NMODES);
575
576         memset(link_info, 0, sizeof(*link_info));
577         if ((link_mode == EFX_LINK_DOWN) || (link_mode == EFX_LINK_UNKNOWN))
578                 link_info->link_status = ETH_LINK_DOWN;
579         else
580                 link_info->link_status = ETH_LINK_UP;
581
582         switch (link_mode) {
583         case EFX_LINK_10HDX:
584                 link_info->link_speed  = ETH_SPEED_NUM_10M;
585                 link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
586                 break;
587         case EFX_LINK_10FDX:
588                 link_info->link_speed  = ETH_SPEED_NUM_10M;
589                 link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
590                 break;
591         case EFX_LINK_100HDX:
592                 link_info->link_speed  = ETH_SPEED_NUM_100M;
593                 link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
594                 break;
595         case EFX_LINK_100FDX:
596                 link_info->link_speed  = ETH_SPEED_NUM_100M;
597                 link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
598                 break;
599         case EFX_LINK_1000HDX:
600                 link_info->link_speed  = ETH_SPEED_NUM_1G;
601                 link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
602                 break;
603         case EFX_LINK_1000FDX:
604                 link_info->link_speed  = ETH_SPEED_NUM_1G;
605                 link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
606                 break;
607         case EFX_LINK_10000FDX:
608                 link_info->link_speed  = ETH_SPEED_NUM_10G;
609                 link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
610                 break;
611         case EFX_LINK_25000FDX:
612                 link_info->link_speed  = ETH_SPEED_NUM_25G;
613                 link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
614                 break;
615         case EFX_LINK_40000FDX:
616                 link_info->link_speed  = ETH_SPEED_NUM_40G;
617                 link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
618                 break;
619         case EFX_LINK_50000FDX:
620                 link_info->link_speed  = ETH_SPEED_NUM_50G;
621                 link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
622                 break;
623         case EFX_LINK_100000FDX:
624                 link_info->link_speed  = ETH_SPEED_NUM_100G;
625                 link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
626                 break;
627         default:
628                 SFC_ASSERT(B_FALSE);
629                 /* FALLTHROUGH */
630         case EFX_LINK_UNKNOWN:
631         case EFX_LINK_DOWN:
632                 link_info->link_speed  = ETH_SPEED_NUM_NONE;
633                 link_info->link_duplex = 0;
634                 break;
635         }
636
637         link_info->link_autoneg = ETH_LINK_AUTONEG;
638 }