Deleted Added
full compact
sfxge_port.c (282897) sfxge_port.c (283007)
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

--- 14 unchanged lines hidden (view full) ---

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>
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

--- 14 unchanged lines hidden (view full) ---

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: head/sys/dev/sfxge/sfxge_port.c 282897 2015-05-14 12:59:17Z arybchik $");
31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge_port.c 283007 2015-05-16 10:35:30Z arybchik $");
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
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
42static int sfxge_phy_cap_mask(struct sfxge_softc *, int, uint32_t *);
43
42static int
43sfxge_mac_stat_update(struct sfxge_softc *sc)
44{
45 struct sfxge_port *port = &sc->port;
46 efsys_mem_t *esmp = &(port->mac_stats.dma_buf);
47 clock_t now;
48 unsigned int count;
49 int rc;

--- 388 unchanged lines hidden (view full) ---

438sfxge_port_start(struct sfxge_softc *sc)
439{
440 uint8_t mac_addr[ETHER_ADDR_LEN];
441 struct ifnet *ifp = sc->ifnet;
442 struct sfxge_port *port;
443 efx_nic_t *enp;
444 size_t pdu;
445 int rc;
44static int
45sfxge_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;

--- 388 unchanged lines hidden (view full) ---

440sfxge_port_start(struct sfxge_softc *sc)
441{
442 uint8_t mac_addr[ETHER_ADDR_LEN];
443 struct ifnet *ifp = sc->ifnet;
444 struct sfxge_port *port;
445 efx_nic_t *enp;
446 size_t pdu;
447 int rc;
448 uint32_t phy_cap_mask;
446
447 port = &sc->port;
448 enp = sc->enp;
449
450 SFXGE_PORT_LOCK(port);
451
452 KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
453 ("port not initialized"));

--- 24 unchanged lines hidden (view full) ---

478 /* Update MAC stats by DMA every second */
479 if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
480 1000, B_FALSE)) != 0)
481 goto fail2;
482
483 if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
484 goto fail3;
485
449
450 port = &sc->port;
451 enp = sc->enp;
452
453 SFXGE_PORT_LOCK(port);
454
455 KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
456 ("port not initialized"));

--- 24 unchanged lines hidden (view full) ---

481 /* Update MAC stats by DMA every second */
482 if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
483 1000, B_FALSE)) != 0)
484 goto fail2;
485
486 if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
487 goto fail3;
488
486 if ((rc = efx_phy_adv_cap_set(sc->enp, sc->media.ifm_cur->ifm_data))
487 != 0)
489 if ((rc = sfxge_phy_cap_mask(sc, sc->media.ifm_cur->ifm_media,
490 &phy_cap_mask)) != 0)
488 goto fail4;
489
491 goto fail4;
492
493 if ((rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask)) != 0)
494 goto fail5;
495
490 port->init_state = SFXGE_PORT_STARTED;
491
492 /* Single poll in case there were missing initial events */
493 SFXGE_PORT_UNLOCK(port);
494 sfxge_mac_poll_work(sc, 0);
495
496 return (0);
497
496 port->init_state = SFXGE_PORT_STARTED;
497
498 /* Single poll in case there were missing initial events */
499 SFXGE_PORT_UNLOCK(port);
500 sfxge_mac_poll_work(sc, 0);
501
502 return (0);
503
504fail5:
498fail4:
499 (void)efx_mac_drain(enp, B_TRUE);
500fail3:
501 (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
502 0, B_FALSE);
503fail2:
504 efx_port_fini(sc->enp);
505fail:

--- 227 unchanged lines hidden (view full) ---

733 mode = sc->port.link_mode;
734 ifmr->ifm_active |= sfxge_link_mode[medium_type][mode];
735 ifmr->ifm_active |= sfxge_port_link_fc_ifm(sc);
736 }
737
738 SFXGE_ADAPTER_UNLOCK(sc);
739}
740
505fail4:
506 (void)efx_mac_drain(enp, B_TRUE);
507fail3:
508 (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
509 0, B_FALSE);
510fail2:
511 efx_port_fini(sc->enp);
512fail:

--- 227 unchanged lines hidden (view full) ---

740 mode = sc->port.link_mode;
741 ifmr->ifm_active |= sfxge_link_mode[medium_type][mode];
742 ifmr->ifm_active |= sfxge_port_link_fc_ifm(sc);
743 }
744
745 SFXGE_ADAPTER_UNLOCK(sc);
746}
747
748static efx_phy_cap_type_t
749sfxge_link_mode_to_phy_cap(efx_link_mode_t mode)
750{
751 switch (mode) {
752 case EFX_LINK_10HDX:
753 return (EFX_PHY_CAP_10HDX);
754 case EFX_LINK_10FDX:
755 return (EFX_PHY_CAP_10FDX);
756 case EFX_LINK_100HDX:
757 return (EFX_PHY_CAP_100HDX);
758 case EFX_LINK_100FDX:
759 return (EFX_PHY_CAP_100FDX);
760 case EFX_LINK_1000HDX:
761 return (EFX_PHY_CAP_1000HDX);
762 case EFX_LINK_1000FDX:
763 return (EFX_PHY_CAP_1000FDX);
764 case EFX_LINK_10000FDX:
765 return (EFX_PHY_CAP_10000FDX);
766 default:
767 EFSYS_ASSERT(B_FALSE);
768 return (EFX_PHY_CAP_INVALID);
769 }
770}
771
741static int
772static int
773sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask)
774{
775 efx_phy_media_type_t medium_type;
776 boolean_t mode_found = B_FALSE;
777 uint32_t cap_mask, mode_cap_mask;
778 efx_link_mode_t mode;
779 efx_phy_cap_type_t phy_cap;
780
781 efx_phy_media_type_get(sc->enp, &medium_type);
782 if (medium_type >= nitems(sfxge_link_mode)) {
783 if_printf(sc->ifnet, "unexpected media type %d\n", medium_type);
784 return (EINVAL);
785 }
786
787 efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
788
789 for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
790 if (ifmedia == sfxge_link_mode[medium_type][mode]) {
791 mode_found = B_TRUE;
792 break;
793 }
794 }
795
796 if (!mode_found) {
797 /*
798 * If media is not in the table, it must be IFM_AUTO.
799 */
800 KASSERT((cap_mask & (1 << EFX_PHY_CAP_AN)) &&
801 ifmedia == (IFM_ETHER | IFM_AUTO),
802 ("%s: no mode for media %d", __func__, ifmedia));
803 *phy_cap_mask = (cap_mask & ~(1 << EFX_PHY_CAP_ASYM));
804 return (0);
805 }
806
807 phy_cap = sfxge_link_mode_to_phy_cap(mode);
808 if (phy_cap == EFX_PHY_CAP_INVALID) {
809 if_printf(sc->ifnet,
810 "cannot map link mode %d to phy capability\n",
811 mode);
812 return (EINVAL);
813 }
814
815 mode_cap_mask = (1 << phy_cap);
816 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN);
817#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
818 if (ifmedia & IFM_ETH_RXPAUSE)
819 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
820 if (!(ifmedia & IFM_ETH_TXPAUSE))
821 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_ASYM);
822#else
823 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
824#endif
825
826 *phy_cap_mask = mode_cap_mask;
827 return (0);
828}
829
830static int
742sfxge_media_change(struct ifnet *ifp)
743{
744 struct sfxge_softc *sc;
745 struct ifmedia_entry *ifm;
746 int rc;
831sfxge_media_change(struct ifnet *ifp)
832{
833 struct sfxge_softc *sc;
834 struct ifmedia_entry *ifm;
835 int rc;
836 uint32_t phy_cap_mask;
747
748 sc = ifp->if_softc;
749 ifm = sc->media.ifm_cur;
750
751 SFXGE_ADAPTER_LOCK(sc);
752
753 if (!SFXGE_RUNNING(sc)) {
754 rc = 0;
755 goto out;
756 }
757
758 rc = efx_mac_fcntl_set(sc->enp, sfxge_port_wanted_fc(sc), B_TRUE);
759 if (rc != 0)
760 goto out;
761
837
838 sc = ifp->if_softc;
839 ifm = sc->media.ifm_cur;
840
841 SFXGE_ADAPTER_LOCK(sc);
842
843 if (!SFXGE_RUNNING(sc)) {
844 rc = 0;
845 goto out;
846 }
847
848 rc = efx_mac_fcntl_set(sc->enp, sfxge_port_wanted_fc(sc), B_TRUE);
849 if (rc != 0)
850 goto out;
851
762 rc = efx_phy_adv_cap_set(sc->enp, ifm->ifm_data);
852 if ((rc = sfxge_phy_cap_mask(sc, ifm->ifm_media, &phy_cap_mask)) != 0)
853 goto out;
854
855 rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask);
763out:
764 SFXGE_ADAPTER_UNLOCK(sc);
765
766 return (rc);
767}
768
769int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
770{
771 efx_phy_media_type_t medium_type;
772 uint32_t cap_mask, mode_cap_mask;
773 efx_link_mode_t mode;
856out:
857 SFXGE_ADAPTER_UNLOCK(sc);
858
859 return (rc);
860}
861
862int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
863{
864 efx_phy_media_type_t medium_type;
865 uint32_t cap_mask, mode_cap_mask;
866 efx_link_mode_t mode;
867 efx_phy_cap_type_t phy_cap;
774 int mode_ifm, best_mode_ifm = 0;
775 int rc;
776
777 /* We need port state to initialise the ifmedia list. */
778 if ((rc = efx_nic_init(sc->enp)) != 0)
779 goto out;
780 if ((rc = efx_port_init(sc->enp)) != 0)
781 goto out2;

--- 14 unchanged lines hidden (view full) ---

796 * Therefore we never disable auto-negotiation.
797 *
798 * Also enable and advertise flow control by default.
799 */
800
801 efx_phy_media_type_get(sc->enp, &medium_type);
802 efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
803
868 int mode_ifm, best_mode_ifm = 0;
869 int rc;
870
871 /* We need port state to initialise the ifmedia list. */
872 if ((rc = efx_nic_init(sc->enp)) != 0)
873 goto out;
874 if ((rc = efx_port_init(sc->enp)) != 0)
875 goto out2;

--- 14 unchanged lines hidden (view full) ---

890 * Therefore we never disable auto-negotiation.
891 *
892 * Also enable and advertise flow control by default.
893 */
894
895 efx_phy_media_type_get(sc->enp, &medium_type);
896 efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
897
804 EFX_STATIC_ASSERT(EFX_LINK_10HDX == EFX_PHY_CAP_10HDX + 1);
805 EFX_STATIC_ASSERT(EFX_LINK_10FDX == EFX_PHY_CAP_10FDX + 1);
806 EFX_STATIC_ASSERT(EFX_LINK_100HDX == EFX_PHY_CAP_100HDX + 1);
807 EFX_STATIC_ASSERT(EFX_LINK_100FDX == EFX_PHY_CAP_100FDX + 1);
808 EFX_STATIC_ASSERT(EFX_LINK_1000HDX == EFX_PHY_CAP_1000HDX + 1);
809 EFX_STATIC_ASSERT(EFX_LINK_1000FDX == EFX_PHY_CAP_1000FDX + 1);
810 EFX_STATIC_ASSERT(EFX_LINK_10000FDX == EFX_PHY_CAP_10000FDX + 1);
898 for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
899 phy_cap = sfxge_link_mode_to_phy_cap(mode);
900 if (phy_cap == EFX_PHY_CAP_INVALID)
901 continue;
811
902
812 for (mode = EFX_LINK_10HDX; mode <= EFX_LINK_10000FDX; mode++) {
813 mode_cap_mask = 1 << (mode - 1);
903 mode_cap_mask = (1 << phy_cap);
814 mode_ifm = sfxge_link_mode[medium_type][mode];
815
816 if ((cap_mask & mode_cap_mask) && mode_ifm) {
904 mode_ifm = sfxge_link_mode[medium_type][mode];
905
906 if ((cap_mask & mode_cap_mask) && mode_ifm) {
817 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN);
818
819#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
820 /* No flow-control */
907 /* No flow-control */
821 ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL);
908 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
822
909
910#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
823 /* Respond-only. If using AN, we implicitly
824 * offer symmetric as well, but that doesn't
825 * mean we *have* to generate pause frames.
826 */
911 /* Respond-only. If using AN, we implicitly
912 * offer symmetric as well, but that doesn't
913 * mean we *have* to generate pause frames.
914 */
827 mode_cap_mask |= cap_mask & ((1 << EFX_PHY_CAP_PAUSE) |
828 (1 << EFX_PHY_CAP_ASYM));
829 mode_ifm |= IFM_ETH_RXPAUSE;
915 mode_ifm |= IFM_ETH_RXPAUSE;
830 ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL);
916 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
831
832 /* Symmetric */
917
918 /* Symmetric */
833 mode_cap_mask &= ~(1 << EFX_PHY_CAP_ASYM);
834 mode_ifm |= IFM_ETH_TXPAUSE;
919 mode_ifm |= IFM_ETH_TXPAUSE;
835#else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */
836 mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
920 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
837#endif
921#endif
838 ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL);
839
840 /* Link modes are numbered in order of speed,
841 * so assume the last one available is the best.
842 */
843 best_mode_ifm = mode_ifm;
844 }
845 }
846
847 if (cap_mask & (1 << EFX_PHY_CAP_AN)) {
848 /* Add autoselect mode. */
849 mode_ifm = IFM_ETHER | IFM_AUTO;
922
923 /* Link modes are numbered in order of speed,
924 * so assume the last one available is the best.
925 */
926 best_mode_ifm = mode_ifm;
927 }
928 }
929
930 if (cap_mask & (1 << EFX_PHY_CAP_AN)) {
931 /* Add autoselect mode. */
932 mode_ifm = IFM_ETHER | IFM_AUTO;
850 ifmedia_add(&sc->media, mode_ifm,
851 cap_mask & ~(1 << EFX_PHY_CAP_ASYM), NULL);
933 ifmedia_add(&sc->media, mode_ifm, 0, NULL);
852 best_mode_ifm = mode_ifm;
853 }
854
855 if (best_mode_ifm != 0)
856 ifmedia_set(&sc->media, best_mode_ifm);
857
858 /* Now discard port state until interface is started. */
859 efx_port_fini(sc->enp);
860out2:
861 efx_nic_fini(sc->enp);
862out:
863 return (rc);
864}
934 best_mode_ifm = mode_ifm;
935 }
936
937 if (best_mode_ifm != 0)
938 ifmedia_set(&sc->media, best_mode_ifm);
939
940 /* Now discard port state until interface is started. */
941 efx_port_fini(sc->enp);
942out2:
943 efx_nic_fini(sc->enp);
944out:
945 return (rc);
946}