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