]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/sfxge/sfxge_port.c
MFC r311983
[FreeBSD/stable/10.git] / sys / dev / sfxge / sfxge_port.c
1 /*-
2  * Copyright (c) 2010-2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * This software was developed in part by Philip Paeps under contract for
6  * Solarflare Communications, Inc.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and documentation are
30  * those of the authors and should not be interpreted as representing official
31  * policies, either expressed or implied, of the FreeBSD Project.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include <sys/types.h>
38 #include <sys/limits.h>
39 #include <net/ethernet.h>
40 #include <net/if_dl.h>
41
42 #include "common/efx.h"
43
44 #include "sfxge.h"
45
46 #define SFXGE_PARAM_STATS_UPDATE_PERIOD_MS \
47         SFXGE_PARAM(stats_update_period_ms)
48 static int sfxge_stats_update_period_ms = SFXGE_STATS_UPDATE_PERIOD_MS;
49 TUNABLE_INT(SFXGE_PARAM_STATS_UPDATE_PERIOD_MS,
50             &sfxge_stats_update_period_ms);
51 SYSCTL_INT(_hw_sfxge, OID_AUTO, stats_update_period_ms, CTLFLAG_RDTUN,
52            &sfxge_stats_update_period_ms, 0,
53            "netstat interface statistics update period in milliseconds");
54
55 static int sfxge_phy_cap_mask(struct sfxge_softc *, int, uint32_t *);
56
57 static int
58 sfxge_mac_stat_update(struct sfxge_softc *sc)
59 {
60         struct sfxge_port *port = &sc->port;
61         efsys_mem_t *esmp = &(port->mac_stats.dma_buf);
62         clock_t now;
63         unsigned int min_ticks;
64         unsigned int count;
65         int rc;
66
67         SFXGE_PORT_LOCK_ASSERT_OWNED(port);
68
69         if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) {
70                 rc = 0;
71                 goto out;
72         }
73
74         min_ticks = (unsigned int)hz * port->stats_update_period_ms / 1000;
75
76         now = ticks;
77         if ((unsigned int)(now - port->mac_stats.update_time) < min_ticks) {
78                 rc = 0;
79                 goto out;
80         }
81
82         port->mac_stats.update_time = now;
83
84         /* If we're unlucky enough to read statistics wduring the DMA, wait
85          * up to 10ms for it to finish (typically takes <500us) */
86         for (count = 0; count < 100; ++count) {
87                 EFSYS_PROBE1(wait, unsigned int, count);
88
89                 /* Try to update the cached counters */
90                 if ((rc = efx_mac_stats_update(sc->enp, esmp,
91                     port->mac_stats.decode_buf, NULL)) != EAGAIN)
92                         goto out;
93
94                 DELAY(100);
95         }
96
97         rc = ETIMEDOUT;
98 out:
99         return (rc);
100 }
101
102 void
103 sfxge_port_update_stats(struct sfxge_softc *sc)
104 {
105         struct ifnet *ifp;
106         uint64_t *mac_stats;
107
108         SFXGE_PORT_LOCK(&sc->port);
109
110         /* Ignore error and use old values */
111         (void)sfxge_mac_stat_update(sc);
112
113         ifp = sc->ifnet;
114         mac_stats = (uint64_t *)sc->port.mac_stats.decode_buf;
115
116         ifp->if_ipackets = mac_stats[EFX_MAC_RX_PKTS];
117         ifp->if_ierrors = mac_stats[EFX_MAC_RX_ERRORS];
118         ifp->if_opackets = mac_stats[EFX_MAC_TX_PKTS];
119         ifp->if_oerrors = mac_stats[EFX_MAC_TX_ERRORS];
120         ifp->if_collisions =
121             mac_stats[EFX_MAC_TX_SGL_COL_PKTS] +
122             mac_stats[EFX_MAC_TX_MULT_COL_PKTS] +
123             mac_stats[EFX_MAC_TX_EX_COL_PKTS] +
124             mac_stats[EFX_MAC_TX_LATE_COL_PKTS];
125         ifp->if_ibytes = mac_stats[EFX_MAC_RX_OCTETS];
126         ifp->if_obytes = mac_stats[EFX_MAC_TX_OCTETS];
127         /* if_imcasts is maintained in net/if_ethersubr.c */
128         ifp->if_omcasts =
129             mac_stats[EFX_MAC_TX_MULTICST_PKTS] +
130             mac_stats[EFX_MAC_TX_BRDCST_PKTS];
131         /* if_iqdrops is maintained in net/if_ethersubr.c */
132         /* if_noproto is maintained in net/if_ethersubr.c */
133
134         SFXGE_PORT_UNLOCK(&sc->port);
135 }
136
137 static int
138 sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS)
139 {
140         struct sfxge_softc *sc = arg1;
141         unsigned int id = arg2;
142         int rc;
143         uint64_t val;
144
145         SFXGE_PORT_LOCK(&sc->port);
146         if ((rc = sfxge_mac_stat_update(sc)) == 0)
147                 val = ((uint64_t *)sc->port.mac_stats.decode_buf)[id];
148         SFXGE_PORT_UNLOCK(&sc->port);
149
150         if (rc == 0)
151                 rc = SYSCTL_OUT(req, &val, sizeof(val));
152         return (rc);
153 }
154
155 static void
156 sfxge_mac_stat_init(struct sfxge_softc *sc)
157 {
158         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
159         struct sysctl_oid_list *stat_list;
160         unsigned int id;
161         const char *name;
162
163         stat_list = SYSCTL_CHILDREN(sc->stats_node);
164
165         /* Initialise the named stats */
166         for (id = 0; id < EFX_MAC_NSTATS; id++) {
167                 name = efx_mac_stat_name(sc->enp, id);
168                 SYSCTL_ADD_PROC(
169                         ctx, stat_list,
170                         OID_AUTO, name, CTLTYPE_U64|CTLFLAG_RD,
171                         sc, id, sfxge_mac_stat_handler, "Q",
172                         "");
173         }
174 }
175
176 #ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
177
178 static unsigned int
179 sfxge_port_wanted_fc(struct sfxge_softc *sc)
180 {
181         struct ifmedia_entry *ifm = sc->media.ifm_cur;
182
183         if (ifm->ifm_media == (IFM_ETHER | IFM_AUTO))
184                 return (EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE);
185         return (((ifm->ifm_media & IFM_ETH_RXPAUSE) ? EFX_FCNTL_RESPOND : 0) |
186                 ((ifm->ifm_media & IFM_ETH_TXPAUSE) ? EFX_FCNTL_GENERATE : 0));
187 }
188
189 static unsigned int
190 sfxge_port_link_fc_ifm(struct sfxge_softc *sc)
191 {
192         unsigned int wanted_fc, link_fc;
193
194         efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc);
195         return ((link_fc & EFX_FCNTL_RESPOND) ? IFM_ETH_RXPAUSE : 0) |
196                 ((link_fc & EFX_FCNTL_GENERATE) ? IFM_ETH_TXPAUSE : 0);
197 }
198
199 #else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */
200
201 static unsigned int
202 sfxge_port_wanted_fc(struct sfxge_softc *sc)
203 {
204         return (sc->port.wanted_fc);
205 }
206
207 static unsigned int
208 sfxge_port_link_fc_ifm(struct sfxge_softc *sc)
209 {
210         return (0);
211 }
212
213 static int
214 sfxge_port_wanted_fc_handler(SYSCTL_HANDLER_ARGS)
215 {
216         struct sfxge_softc *sc;
217         struct sfxge_port *port;
218         unsigned int fcntl;
219         int error;
220
221         sc = arg1;
222         port = &sc->port;
223
224         if (req->newptr != NULL) {
225                 if ((error = SYSCTL_IN(req, &fcntl, sizeof(fcntl))) != 0)
226                         return (error);
227
228                 SFXGE_PORT_LOCK(port);
229
230                 if (port->wanted_fc != fcntl) {
231                         if (port->init_state == SFXGE_PORT_STARTED)
232                                 error = efx_mac_fcntl_set(sc->enp,
233                                                           port->wanted_fc,
234                                                           B_TRUE);
235                         if (error == 0)
236                                 port->wanted_fc = fcntl;
237                 }
238
239                 SFXGE_PORT_UNLOCK(port);
240         } else {
241                 SFXGE_PORT_LOCK(port);
242                 fcntl = port->wanted_fc;
243                 SFXGE_PORT_UNLOCK(port);
244
245                 error = SYSCTL_OUT(req, &fcntl, sizeof(fcntl));
246         }
247
248         return (error);
249 }
250
251 static int
252 sfxge_port_link_fc_handler(SYSCTL_HANDLER_ARGS)
253 {
254         struct sfxge_softc *sc;
255         struct sfxge_port *port;
256         unsigned int wanted_fc, link_fc;
257
258         sc = arg1;
259         port = &sc->port;
260
261         SFXGE_PORT_LOCK(port);
262         if (__predict_true(port->init_state == SFXGE_PORT_STARTED) &&
263             SFXGE_LINK_UP(sc))
264                 efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc);
265         else
266                 link_fc = 0;
267         SFXGE_PORT_UNLOCK(port);
268
269         return (SYSCTL_OUT(req, &link_fc, sizeof(link_fc)));
270 }
271
272 #endif /* SFXGE_HAVE_PAUSE_MEDIAOPTS */
273
274 static const uint64_t sfxge_link_baudrate[EFX_LINK_NMODES] = {
275         [EFX_LINK_10HDX]        = IF_Mbps(10),
276         [EFX_LINK_10FDX]        = IF_Mbps(10),
277         [EFX_LINK_100HDX]       = IF_Mbps(100),
278         [EFX_LINK_100FDX]       = IF_Mbps(100),
279         [EFX_LINK_1000HDX]      = IF_Gbps(1),
280         [EFX_LINK_1000FDX]      = IF_Gbps(1),
281         [EFX_LINK_10000FDX]     = IF_Gbps(10),
282         [EFX_LINK_40000FDX]     = IF_Gbps(40),
283 };
284
285 void
286 sfxge_mac_link_update(struct sfxge_softc *sc, efx_link_mode_t mode)
287 {
288         struct sfxge_port *port;
289         int link_state;
290
291         port = &sc->port;
292
293         if (port->link_mode == mode)
294                 return;
295
296         port->link_mode = mode;
297
298         /* Push link state update to the OS */
299         link_state = (SFXGE_LINK_UP(sc) ? LINK_STATE_UP : LINK_STATE_DOWN);
300         if_initbaudrate(sc->ifnet, sfxge_link_baudrate[port->link_mode]);
301         if_link_state_change(sc->ifnet, link_state);
302 }
303
304 static void
305 sfxge_mac_poll_work(void *arg, int npending)
306 {
307         struct sfxge_softc *sc;
308         efx_nic_t *enp;
309         struct sfxge_port *port;
310         efx_link_mode_t mode;
311
312         sc = (struct sfxge_softc *)arg;
313         enp = sc->enp;
314         port = &sc->port;
315
316         SFXGE_PORT_LOCK(port);
317
318         if (__predict_false(port->init_state != SFXGE_PORT_STARTED))
319                 goto done;
320
321         /* This may sleep waiting for MCDI completion */
322         (void)efx_port_poll(enp, &mode);
323         sfxge_mac_link_update(sc, mode);
324
325 done:
326         SFXGE_PORT_UNLOCK(port);
327 }
328
329 static int
330 sfxge_mac_multicast_list_set(struct sfxge_softc *sc)
331 {
332         struct ifnet *ifp = sc->ifnet;
333         struct sfxge_port *port = &sc->port;
334         uint8_t *mcast_addr = port->mcast_addrs;
335         struct ifmultiaddr *ifma;
336         struct sockaddr_dl *sa;
337         int rc = 0;
338
339         mtx_assert(&port->lock, MA_OWNED);
340
341         port->mcast_count = 0;
342         if_maddr_rlock(ifp);
343         TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
344                 if (ifma->ifma_addr->sa_family == AF_LINK) {
345                         if (port->mcast_count == EFX_MAC_MULTICAST_LIST_MAX) {
346                                 device_printf(sc->dev,
347                                     "Too many multicast addresses\n");
348                                 rc = EINVAL;
349                                 break;
350                         }
351
352                         sa = (struct sockaddr_dl *)ifma->ifma_addr;
353                         memcpy(mcast_addr, LLADDR(sa), EFX_MAC_ADDR_LEN);
354                         mcast_addr += EFX_MAC_ADDR_LEN;
355                         ++port->mcast_count;
356                 }
357         }
358         if_maddr_runlock(ifp);
359
360         if (rc == 0) {
361                 rc = efx_mac_multicast_list_set(sc->enp, port->mcast_addrs,
362                                                 port->mcast_count);
363                 if (rc != 0)
364                         device_printf(sc->dev,
365                             "Cannot set multicast address list\n");
366         }
367
368         return (rc);
369 }
370
371 static int
372 sfxge_mac_filter_set_locked(struct sfxge_softc *sc)
373 {
374         struct ifnet *ifp = sc->ifnet;
375         struct sfxge_port *port = &sc->port;
376         boolean_t all_mulcst;
377         int rc;
378
379         mtx_assert(&port->lock, MA_OWNED);
380
381         all_mulcst = !!(ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI));
382
383         rc = sfxge_mac_multicast_list_set(sc);
384         /* Fallback to all multicast if cannot set multicast list */
385         if (rc != 0)
386                 all_mulcst = B_TRUE;
387
388         rc = efx_mac_filter_set(sc->enp, !!(ifp->if_flags & IFF_PROMISC),
389                                 (port->mcast_count > 0), all_mulcst, B_TRUE);
390
391         return (rc);
392 }
393
394 int
395 sfxge_mac_filter_set(struct sfxge_softc *sc)
396 {
397         struct sfxge_port *port = &sc->port;
398         int rc;
399
400         SFXGE_PORT_LOCK(port);
401         /*
402          * The function may be called without softc_lock held in the
403          * case of SIOCADDMULTI and SIOCDELMULTI ioctls. ioctl handler
404          * checks IFF_DRV_RUNNING flag which implies port started, but
405          * it is not guaranteed to remain. softc_lock shared lock can't
406          * be held in the case of these ioctls processing, since it
407          * results in failure where kernel complains that non-sleepable
408          * lock is held in sleeping thread. Both problems are repeatable
409          * on LAG with LACP proto bring up.
410          */
411         if (__predict_true(port->init_state == SFXGE_PORT_STARTED))
412                 rc = sfxge_mac_filter_set_locked(sc);
413         else
414                 rc = 0;
415         SFXGE_PORT_UNLOCK(port);
416         return (rc);
417 }
418
419 void
420 sfxge_port_stop(struct sfxge_softc *sc)
421 {
422         struct sfxge_port *port;
423         efx_nic_t *enp;
424
425         port = &sc->port;
426         enp = sc->enp;
427
428         SFXGE_PORT_LOCK(port);
429
430         KASSERT(port->init_state == SFXGE_PORT_STARTED,
431             ("port not started"));
432
433         port->init_state = SFXGE_PORT_INITIALIZED;
434
435         port->mac_stats.update_time = 0;
436
437         /* This may call MCDI */
438         (void)efx_mac_drain(enp, B_TRUE);
439
440         (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE);
441
442         port->link_mode = EFX_LINK_UNKNOWN;
443
444         /* Destroy the common code port object. */
445         efx_port_fini(enp);
446
447         efx_filter_fini(enp);
448
449         SFXGE_PORT_UNLOCK(port);
450 }
451
452 int
453 sfxge_port_start(struct sfxge_softc *sc)
454 {
455         uint8_t mac_addr[ETHER_ADDR_LEN];
456         struct ifnet *ifp = sc->ifnet;
457         struct sfxge_port *port;
458         efx_nic_t *enp;
459         size_t pdu;
460         int rc;
461         uint32_t phy_cap_mask;
462
463         port = &sc->port;
464         enp = sc->enp;
465
466         SFXGE_PORT_LOCK(port);
467
468         KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
469             ("port not initialized"));
470
471         /* Initialise the required filtering */
472         if ((rc = efx_filter_init(enp)) != 0)
473                 goto fail_filter_init;
474
475         /* Initialize the port object in the common code. */
476         if ((rc = efx_port_init(sc->enp)) != 0)
477                 goto fail;
478
479         /* Set the SDU */
480         pdu = EFX_MAC_PDU(ifp->if_mtu);
481         if ((rc = efx_mac_pdu_set(enp, pdu)) != 0)
482                 goto fail2;
483
484         if ((rc = efx_mac_fcntl_set(enp, sfxge_port_wanted_fc(sc), B_TRUE))
485             != 0)
486                 goto fail3;
487
488         /* Set the unicast address */
489         if_addr_rlock(ifp);
490         bcopy(LLADDR((struct sockaddr_dl *)ifp->if_addr->ifa_addr),
491               mac_addr, sizeof(mac_addr));
492         if_addr_runlock(ifp);
493         if ((rc = efx_mac_addr_set(enp, mac_addr)) != 0)
494                 goto fail4;
495
496         sfxge_mac_filter_set_locked(sc);
497
498         /* Update MAC stats by DMA every period */
499         if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
500                                          port->stats_update_period_ms,
501                                          B_FALSE)) != 0)
502                 goto fail6;
503
504         if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
505                 goto fail8;
506
507         if ((rc = sfxge_phy_cap_mask(sc, sc->media.ifm_cur->ifm_media,
508                                      &phy_cap_mask)) != 0)
509                 goto fail9;
510
511         if ((rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask)) != 0)
512                 goto fail10;
513
514         port->init_state = SFXGE_PORT_STARTED;
515
516         /* Single poll in case there were missing initial events */
517         SFXGE_PORT_UNLOCK(port);
518         sfxge_mac_poll_work(sc, 0);
519
520         return (0);
521
522 fail10:
523 fail9:
524         (void)efx_mac_drain(enp, B_TRUE);
525 fail8:
526         (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE);
527 fail6:
528 fail4:
529 fail3:
530
531 fail2:
532         efx_port_fini(enp);
533 fail:
534         efx_filter_fini(enp);
535 fail_filter_init:
536         SFXGE_PORT_UNLOCK(port);
537
538         return (rc);
539 }
540
541 static int
542 sfxge_phy_stat_update(struct sfxge_softc *sc)
543 {
544         struct sfxge_port *port = &sc->port;
545         efsys_mem_t *esmp = &port->phy_stats.dma_buf;
546         clock_t now;
547         unsigned int count;
548         int rc;
549
550         SFXGE_PORT_LOCK_ASSERT_OWNED(port);
551
552         if (__predict_false(port->init_state != SFXGE_PORT_STARTED)) {
553                 rc = 0;
554                 goto out;
555         }
556
557         now = ticks;
558         if ((unsigned int)(now - port->phy_stats.update_time) < (unsigned int)hz) {
559                 rc = 0;
560                 goto out;
561         }
562
563         port->phy_stats.update_time = now;
564
565         /* If we're unlucky enough to read statistics wduring the DMA, wait
566          * up to 10ms for it to finish (typically takes <500us) */
567         for (count = 0; count < 100; ++count) {
568                 EFSYS_PROBE1(wait, unsigned int, count);
569
570                 /* Synchronize the DMA memory for reading */
571                 bus_dmamap_sync(esmp->esm_tag, esmp->esm_map,
572                     BUS_DMASYNC_POSTREAD);
573
574                 /* Try to update the cached counters */
575                 if ((rc = efx_phy_stats_update(sc->enp, esmp,
576                     port->phy_stats.decode_buf)) != EAGAIN)
577                         goto out;
578
579                 DELAY(100);
580         }
581
582         rc = ETIMEDOUT;
583 out:
584         return (rc);
585 }
586
587 static int
588 sfxge_phy_stat_handler(SYSCTL_HANDLER_ARGS)
589 {
590         struct sfxge_softc *sc = arg1;
591         unsigned int id = arg2;
592         int rc;
593         uint32_t val;
594
595         SFXGE_PORT_LOCK(&sc->port);
596         if ((rc = sfxge_phy_stat_update(sc)) == 0)
597                 val = ((uint32_t *)sc->port.phy_stats.decode_buf)[id];
598         SFXGE_PORT_UNLOCK(&sc->port);
599
600         if (rc == 0)
601                 rc = SYSCTL_OUT(req, &val, sizeof(val));
602         return (rc);
603 }
604
605 static void
606 sfxge_phy_stat_init(struct sfxge_softc *sc)
607 {
608         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
609         struct sysctl_oid_list *stat_list;
610         unsigned int id;
611         const char *name;
612         uint64_t stat_mask = efx_nic_cfg_get(sc->enp)->enc_phy_stat_mask;
613
614         stat_list = SYSCTL_CHILDREN(sc->stats_node);
615
616         /* Initialise the named stats */
617         for (id = 0; id < EFX_PHY_NSTATS; id++) {
618                 if (!(stat_mask & ((uint64_t)1 << id)))
619                         continue;
620                 name = efx_phy_stat_name(sc->enp, id);
621                 SYSCTL_ADD_PROC(
622                         ctx, stat_list,
623                         OID_AUTO, name, CTLTYPE_UINT|CTLFLAG_RD,
624                         sc, id, sfxge_phy_stat_handler,
625                         id == EFX_PHY_STAT_OUI ? "IX" : "IU",
626                         "");
627         }
628 }
629
630 void
631 sfxge_port_fini(struct sfxge_softc *sc)
632 {
633         struct sfxge_port *port;
634         efsys_mem_t *esmp;
635
636         port = &sc->port;
637         esmp = &port->mac_stats.dma_buf;
638
639         KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
640             ("Port not initialized"));
641
642         port->init_state = SFXGE_PORT_UNINITIALIZED;
643
644         port->link_mode = EFX_LINK_UNKNOWN;
645
646         /* Finish with PHY DMA memory */
647         sfxge_dma_free(&port->phy_stats.dma_buf);
648         free(port->phy_stats.decode_buf, M_SFXGE);
649
650         sfxge_dma_free(esmp);
651         free(port->mac_stats.decode_buf, M_SFXGE);
652
653         SFXGE_PORT_LOCK_DESTROY(port);
654
655         port->sc = NULL;
656 }
657
658 static uint16_t
659 sfxge_port_stats_update_period_ms(struct sfxge_softc *sc)
660 {
661         int period_ms = sfxge_stats_update_period_ms;
662
663         if (period_ms < 0) {
664                 device_printf(sc->dev,
665                         "treat negative stats update period %d as 0 (disable)\n",
666                          period_ms);
667                 period_ms = 0;
668         } else if (period_ms > UINT16_MAX) {
669                 device_printf(sc->dev,
670                         "treat too big stats update period %d as %u\n",
671                         period_ms, UINT16_MAX);
672                 period_ms = UINT16_MAX;
673         }
674
675         return period_ms;
676 }
677
678 static int
679 sfxge_port_stats_update_period_ms_handler(SYSCTL_HANDLER_ARGS)
680 {
681         struct sfxge_softc *sc;
682         struct sfxge_port *port;
683         unsigned int period_ms;
684         int error;
685
686         sc = arg1;
687         port = &sc->port;
688
689         if (req->newptr != NULL) {
690                 error = SYSCTL_IN(req, &period_ms, sizeof(period_ms));
691                 if (error != 0)
692                         return (error);
693
694                 if (period_ms > UINT16_MAX)
695                         return (EINVAL);
696
697                 SFXGE_PORT_LOCK(port);
698
699                 if (port->stats_update_period_ms != period_ms) {
700                         if (port->init_state == SFXGE_PORT_STARTED)
701                                 error = efx_mac_stats_periodic(sc->enp,
702                                                 &port->mac_stats.dma_buf,
703                                                 period_ms, B_FALSE);
704                         if (error == 0)
705                                 port->stats_update_period_ms = period_ms;
706                 }
707
708                 SFXGE_PORT_UNLOCK(port);
709         } else {
710                 SFXGE_PORT_LOCK(port);
711                 period_ms = port->stats_update_period_ms;
712                 SFXGE_PORT_UNLOCK(port);
713
714                 error = SYSCTL_OUT(req, &period_ms, sizeof(period_ms));
715         }
716
717         return (error);
718 }
719
720 int
721 sfxge_port_init(struct sfxge_softc *sc)
722 {
723         struct sfxge_port *port;
724         struct sysctl_ctx_list *sysctl_ctx;
725         struct sysctl_oid *sysctl_tree;
726         efsys_mem_t *mac_stats_buf, *phy_stats_buf;
727         int rc;
728
729         port = &sc->port;
730         mac_stats_buf = &port->mac_stats.dma_buf;
731         phy_stats_buf = &port->phy_stats.dma_buf;
732
733         KASSERT(port->init_state == SFXGE_PORT_UNINITIALIZED,
734             ("Port already initialized"));
735
736         port->sc = sc;
737
738         SFXGE_PORT_LOCK_INIT(port, device_get_nameunit(sc->dev));
739
740         DBGPRINT(sc->dev, "alloc PHY stats");
741         port->phy_stats.decode_buf = malloc(EFX_PHY_NSTATS * sizeof(uint32_t),
742                                             M_SFXGE, M_WAITOK | M_ZERO);
743         if ((rc = sfxge_dma_alloc(sc, EFX_PHY_STATS_SIZE, phy_stats_buf)) != 0)
744                 goto fail;
745         sfxge_phy_stat_init(sc);
746
747         DBGPRINT(sc->dev, "init sysctl");
748         sysctl_ctx = device_get_sysctl_ctx(sc->dev);
749         sysctl_tree = device_get_sysctl_tree(sc->dev);
750
751 #ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS
752         /* If flow control cannot be configured or reported through
753          * ifmedia, provide sysctls for it. */
754         port->wanted_fc = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
755         SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
756             "wanted_fc", CTLTYPE_UINT|CTLFLAG_RW, sc, 0,
757             sfxge_port_wanted_fc_handler, "IU", "wanted flow control mode");
758         SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
759             "link_fc", CTLTYPE_UINT|CTLFLAG_RD, sc, 0,
760             sfxge_port_link_fc_handler, "IU", "link flow control mode");
761 #endif
762
763         DBGPRINT(sc->dev, "alloc MAC stats");
764         port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t),
765                                             M_SFXGE, M_WAITOK | M_ZERO);
766         if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0)
767                 goto fail2;
768         port->stats_update_period_ms = sfxge_port_stats_update_period_ms(sc);
769         sfxge_mac_stat_init(sc);
770
771         SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
772             "stats_update_period_ms", CTLTYPE_UINT|CTLFLAG_RW, sc, 0,
773             sfxge_port_stats_update_period_ms_handler, "IU",
774             "interface statistics refresh period");
775
776         port->init_state = SFXGE_PORT_INITIALIZED;
777
778         DBGPRINT(sc->dev, "success");
779         return (0);
780
781 fail2:
782         free(port->mac_stats.decode_buf, M_SFXGE);
783         sfxge_dma_free(phy_stats_buf);
784 fail:
785         free(port->phy_stats.decode_buf, M_SFXGE);
786         SFXGE_PORT_LOCK_DESTROY(port);
787         port->sc = NULL;
788         DBGPRINT(sc->dev, "failed %d", rc);
789         return (rc);
790 }
791
792 static const int sfxge_link_mode[EFX_PHY_MEDIA_NTYPES][EFX_LINK_NMODES] = {
793         [EFX_PHY_MEDIA_CX4] = {
794                 [EFX_LINK_10000FDX]     = IFM_ETHER | IFM_FDX | IFM_10G_CX4,
795         },
796         [EFX_PHY_MEDIA_KX4] = {
797                 [EFX_LINK_10000FDX]     = IFM_ETHER | IFM_FDX | IFM_10G_KX4,
798         },
799         [EFX_PHY_MEDIA_XFP] = {
800                 /* Don't know the module type, but assume SR for now. */
801                 [EFX_LINK_10000FDX]     = IFM_ETHER | IFM_FDX | IFM_10G_SR,
802         },
803         [EFX_PHY_MEDIA_QSFP_PLUS] = {
804                 /* Don't know the module type, but assume SR for now. */
805                 [EFX_LINK_10000FDX]     = IFM_ETHER | IFM_FDX | IFM_10G_SR,
806                 [EFX_LINK_40000FDX]     = IFM_ETHER | IFM_FDX | IFM_40G_CR4,
807         },
808         [EFX_PHY_MEDIA_SFP_PLUS] = {
809                 /* Don't know the module type, but assume SX/SR for now. */
810                 [EFX_LINK_1000FDX]      = IFM_ETHER | IFM_FDX | IFM_1000_SX,
811                 [EFX_LINK_10000FDX]     = IFM_ETHER | IFM_FDX | IFM_10G_SR,
812         },
813         [EFX_PHY_MEDIA_BASE_T] = {
814                 [EFX_LINK_10HDX]        = IFM_ETHER | IFM_HDX | IFM_10_T,
815                 [EFX_LINK_10FDX]        = IFM_ETHER | IFM_FDX | IFM_10_T,
816                 [EFX_LINK_100HDX]       = IFM_ETHER | IFM_HDX | IFM_100_TX,
817                 [EFX_LINK_100FDX]       = IFM_ETHER | IFM_FDX | IFM_100_TX,
818                 [EFX_LINK_1000HDX]      = IFM_ETHER | IFM_HDX | IFM_1000_T,
819                 [EFX_LINK_1000FDX]      = IFM_ETHER | IFM_FDX | IFM_1000_T,
820                 [EFX_LINK_10000FDX]     = IFM_ETHER | IFM_FDX | IFM_10G_T,
821         },
822 };
823
824 static void
825 sfxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
826 {
827         struct sfxge_softc *sc;
828         efx_phy_media_type_t medium_type;
829         efx_link_mode_t mode;
830
831         sc = ifp->if_softc;
832         SFXGE_ADAPTER_LOCK(sc);
833
834         ifmr->ifm_status = IFM_AVALID;
835         ifmr->ifm_active = IFM_ETHER;
836
837         if (SFXGE_RUNNING(sc) && SFXGE_LINK_UP(sc)) {
838                 ifmr->ifm_status |= IFM_ACTIVE;
839
840                 efx_phy_media_type_get(sc->enp, &medium_type);
841                 mode = sc->port.link_mode;
842                 ifmr->ifm_active |= sfxge_link_mode[medium_type][mode];
843                 ifmr->ifm_active |= sfxge_port_link_fc_ifm(sc);
844         }
845
846         SFXGE_ADAPTER_UNLOCK(sc);
847 }
848
849 static efx_phy_cap_type_t
850 sfxge_link_mode_to_phy_cap(efx_link_mode_t mode)
851 {
852         switch (mode) {
853         case EFX_LINK_10HDX:
854                 return (EFX_PHY_CAP_10HDX);
855         case EFX_LINK_10FDX:
856                 return (EFX_PHY_CAP_10FDX);
857         case EFX_LINK_100HDX:
858                 return (EFX_PHY_CAP_100HDX);
859         case EFX_LINK_100FDX:
860                 return (EFX_PHY_CAP_100FDX);
861         case EFX_LINK_1000HDX:
862                 return (EFX_PHY_CAP_1000HDX);
863         case EFX_LINK_1000FDX:
864                 return (EFX_PHY_CAP_1000FDX);
865         case EFX_LINK_10000FDX:
866                 return (EFX_PHY_CAP_10000FDX);
867         case EFX_LINK_40000FDX:
868                 return (EFX_PHY_CAP_40000FDX);
869         default:
870                 EFSYS_ASSERT(B_FALSE);
871                 return (EFX_PHY_CAP_INVALID);
872         }
873 }
874
875 static int
876 sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask)
877 {
878         /* Get global options (duplex), type and subtype bits */
879         int ifmedia_masked = ifmedia & (IFM_GMASK | IFM_NMASK | IFM_TMASK);
880         efx_phy_media_type_t medium_type;
881         boolean_t mode_found = B_FALSE;
882         uint32_t cap_mask, mode_cap_mask;
883         efx_link_mode_t mode;
884         efx_phy_cap_type_t phy_cap;
885
886         efx_phy_media_type_get(sc->enp, &medium_type);
887         if (medium_type >= nitems(sfxge_link_mode)) {
888                 if_printf(sc->ifnet, "unexpected media type %d\n", medium_type);
889                 return (EINVAL);
890         }
891
892         efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
893
894         for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
895                 if (ifmedia_masked == sfxge_link_mode[medium_type][mode]) {
896                         mode_found = B_TRUE;
897                         break;
898                 }
899         }
900
901         if (!mode_found) {
902                 /*
903                  * If media is not in the table, it must be IFM_AUTO.
904                  */
905                 KASSERT((cap_mask & (1 << EFX_PHY_CAP_AN)) &&
906                     ifmedia_masked == (IFM_ETHER | IFM_AUTO),
907                     ("%s: no mode for media %#x", __func__, ifmedia));
908                 *phy_cap_mask = (cap_mask & ~(1 << EFX_PHY_CAP_ASYM));
909                 return (0);
910         }
911
912         phy_cap = sfxge_link_mode_to_phy_cap(mode);
913         if (phy_cap == EFX_PHY_CAP_INVALID) {
914                 if_printf(sc->ifnet,
915                           "cannot map link mode %d to phy capability\n",
916                           mode);
917                 return (EINVAL);
918         }
919
920         mode_cap_mask = (1 << phy_cap);
921         mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN);
922 #ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
923         if (ifmedia & IFM_ETH_RXPAUSE)
924                 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
925         if (!(ifmedia & IFM_ETH_TXPAUSE))
926                 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_ASYM);
927 #else
928         mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
929 #endif
930
931         *phy_cap_mask = mode_cap_mask;
932         return (0);
933 }
934
935 static int
936 sfxge_media_change(struct ifnet *ifp)
937 {
938         struct sfxge_softc *sc;
939         struct ifmedia_entry *ifm;
940         int rc;
941         uint32_t phy_cap_mask;
942
943         sc = ifp->if_softc;
944         ifm = sc->media.ifm_cur;
945
946         SFXGE_ADAPTER_LOCK(sc);
947
948         if (!SFXGE_RUNNING(sc)) {
949                 rc = 0;
950                 goto out;
951         }
952
953         rc = efx_mac_fcntl_set(sc->enp, sfxge_port_wanted_fc(sc), B_TRUE);
954         if (rc != 0)
955                 goto out;
956
957         if ((rc = sfxge_phy_cap_mask(sc, ifm->ifm_media, &phy_cap_mask)) != 0)
958                 goto out;
959
960         rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask);
961 out:
962         SFXGE_ADAPTER_UNLOCK(sc);
963
964         return (rc);
965 }
966
967 int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
968 {
969         efx_phy_media_type_t medium_type;
970         uint32_t cap_mask, mode_cap_mask;
971         efx_link_mode_t mode;
972         efx_phy_cap_type_t phy_cap;
973         int mode_ifm, best_mode_ifm = 0;
974         int rc;
975
976         /*
977          * We need port state to initialise the ifmedia list.
978          * It requires initialized NIC what is already done in
979          * sfxge_create() when resources are estimated.
980          */
981         if ((rc = efx_filter_init(sc->enp)) != 0)
982                 goto out1;
983         if ((rc = efx_port_init(sc->enp)) != 0)
984                 goto out2;
985
986         /*
987          * Register ifconfig callbacks for querying and setting the
988          * link mode and link status.
989          */
990         ifmedia_init(&sc->media, IFM_IMASK, sfxge_media_change,
991             sfxge_media_status);
992
993         /*
994          * Map firmware medium type and capabilities to ifmedia types.
995          * ifmedia does not distinguish between forcing the link mode
996          * and disabling auto-negotiation.  1000BASE-T and 10GBASE-T
997          * require AN even if only one link mode is enabled, and for
998          * 100BASE-TX it is useful even if the link mode is forced.
999          * Therefore we never disable auto-negotiation.
1000          *
1001          * Also enable and advertise flow control by default.
1002          */
1003
1004         efx_phy_media_type_get(sc->enp, &medium_type);
1005         efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
1006
1007         for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
1008                 phy_cap = sfxge_link_mode_to_phy_cap(mode);
1009                 if (phy_cap == EFX_PHY_CAP_INVALID)
1010                         continue;
1011
1012                 mode_cap_mask = (1 << phy_cap);
1013                 mode_ifm = sfxge_link_mode[medium_type][mode];
1014
1015                 if ((cap_mask & mode_cap_mask) && mode_ifm) {
1016                         /* No flow-control */
1017                         ifmedia_add(&sc->media, mode_ifm, 0, NULL);
1018
1019 #ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
1020                         /* Respond-only.  If using AN, we implicitly
1021                          * offer symmetric as well, but that doesn't
1022                          * mean we *have* to generate pause frames.
1023                          */
1024                         mode_ifm |= IFM_ETH_RXPAUSE;
1025                         ifmedia_add(&sc->media, mode_ifm, 0, NULL);
1026
1027                         /* Symmetric */
1028                         mode_ifm |= IFM_ETH_TXPAUSE;
1029                         ifmedia_add(&sc->media, mode_ifm, 0, NULL);
1030 #endif
1031
1032                         /* Link modes are numbered in order of speed,
1033                          * so assume the last one available is the best.
1034                          */
1035                         best_mode_ifm = mode_ifm;
1036                 }
1037         }
1038
1039         if (cap_mask & (1 << EFX_PHY_CAP_AN)) {
1040                 /* Add autoselect mode. */
1041                 mode_ifm = IFM_ETHER | IFM_AUTO;
1042                 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
1043                 best_mode_ifm = mode_ifm;
1044         }
1045
1046         if (best_mode_ifm != 0)
1047                 ifmedia_set(&sc->media, best_mode_ifm);
1048
1049         /* Now discard port state until interface is started. */
1050         efx_port_fini(sc->enp);
1051 out2:
1052         efx_filter_fini(sc->enp);
1053 out1:
1054         return (rc);
1055 }