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