Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-enetc-remove-bootloader-dependency'

Michael Walle says:

====================
net: enetc: remove bootloader dependency

These patches were picked from the following series:
https://lore.kernel.org/netdev/1567779344-30965-1-git-send-email-claudiu.manoil@nxp.com/
They have never been resent. I've picked them up, addressed Andrews
comments, fixed some more bugs and asked Claudiu if I can keep their SOB
tags; he agreed. I've tested this on our board which happens to have a
bootloader which doesn't do the enetc setup in all cases. Though, only
SGMII mode was tested.

changes since v6:
- dropped _LPA_ infix for USXGMII constants

changes since v5:
- fixed pcs->autoneg_complete and pcs->link assignment. Thanks Vladimir.

changes since v4:
- moved (and renamed) the USXGMII constants to include/uapi/linux/mdio.h.
Suggested by Russell King.

changes since v3:
- rebased to latest net-next where devm_mdiobus_free() was removed.
replace it by mdiobus_free(). The internal MDIO bus is optional, if
there is any error, we try to run with the bootloader default PCS
settings, thus in the error case, we need to free the mdiobus.

changes since v2:
- removed SOBs from "net: enetc: Initialize SerDes for SGMII and USXGMII
protocols" because almost everything has changed.
- get a phy_device for the internal PCS PHY so we can use the phy_
functions instead of raw mdiobus writes
- reuse macros already defined in fsl_mdio.h, move missing bits from
felix to fsl_mdio.h, because they share the same PCS PHY building
block
- added 2500BaseX mode (based on felix init routine)
- changed xgmii mode to usxgmii mode, because it is actually USXGMII and
felix does the same.
- fixed devad, which is 0x1f (MMD_VEND2)

changes since v1:
- mdiobus id is '"imdio-%s", dev_name(dev)' because the plain dev_name()
is used by the emdio.
- use mdiobus_write() instead of imdio->write(imdio, ..), since this is
already a full featured mdiobus
- set phy_mask to ~0 to avoid scanning the bus
- use phy_interface_mode_is_rgmii(phy_mode) to also include the RGMII
modes with pad delays.
- move enetc_imdio_init() to enetc_pf.c, there shouldn't be any other
users, should it?
- renamed serdes to SerDes
- printing the error code of mdiobus_register() in the error path
- call mdiobus_unregister() on _remove()
- call devm_mdiobus_free() if mdiobus_register() fails, since an
error is not fatal
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+210 -57
+12 -33
drivers/net/dsa/ocelot/felix_vsc9959.c
··· 11 11 #include <linux/packing.h> 12 12 #include <net/pkt_sched.h> 13 13 #include <linux/iopoll.h> 14 + #include <linux/mdio.h> 14 15 #include <linux/pci.h> 15 16 #include "felix.h" 16 17 17 18 #define VSC9959_VCAP_IS2_CNT 1024 18 19 #define VSC9959_VCAP_IS2_ENTRY_WIDTH 376 19 20 #define VSC9959_VCAP_PORT_CNT 6 20 - 21 - /* TODO: should find a better place for these */ 22 - #define USXGMII_BMCR_RESET BIT(15) 23 - #define USXGMII_BMCR_AN_EN BIT(12) 24 - #define USXGMII_BMCR_RST_AN BIT(9) 25 - #define USXGMII_BMSR_LNKS(status) (((status) & GENMASK(2, 2)) >> 2) 26 - #define USXGMII_BMSR_AN_CMPL(status) (((status) & GENMASK(5, 5)) >> 5) 27 - #define USXGMII_ADVERTISE_LNKS(x) (((x) << 15) & BIT(15)) 28 - #define USXGMII_ADVERTISE_FDX BIT(12) 29 - #define USXGMII_ADVERTISE_SPEED(x) (((x) << 9) & GENMASK(11, 9)) 30 - #define USXGMII_LPA_LNKS(lpa) ((lpa) >> 15) 31 - #define USXGMII_LPA_DUPLEX(lpa) (((lpa) & GENMASK(12, 12)) >> 12) 32 - #define USXGMII_LPA_SPEED(lpa) (((lpa) & GENMASK(11, 9)) >> 9) 33 - 34 21 #define VSC9959_TAS_GCL_ENTRY_MAX 63 35 - 36 - enum usxgmii_speed { 37 - USXGMII_SPEED_10 = 0, 38 - USXGMII_SPEED_100 = 1, 39 - USXGMII_SPEED_1000 = 2, 40 - USXGMII_SPEED_2500 = 4, 41 - }; 42 22 43 23 static const u32 vsc9959_ana_regmap[] = { 44 24 REG(ANA_ADVLEARN, 0x0089a0), ··· 825 845 { 826 846 /* Configure device ability for the USXGMII Replicator */ 827 847 phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE, 828 - USXGMII_ADVERTISE_SPEED(USXGMII_SPEED_2500) | 829 - USXGMII_ADVERTISE_LNKS(1) | 848 + MDIO_USXGMII_2500FULL | 849 + MDIO_USXGMII_LINK | 830 850 ADVERTISE_SGMII | 831 - ADVERTISE_LPACK | 832 - USXGMII_ADVERTISE_FDX); 851 + ADVERTISE_LPACK); 833 852 } 834 853 835 854 void vsc9959_pcs_config(struct ocelot *ocelot, int port, ··· 1042 1063 return; 1043 1064 1044 1065 pcs->autoneg = true; 1045 - pcs->autoneg_complete = USXGMII_BMSR_AN_CMPL(status); 1046 - pcs->link = USXGMII_BMSR_LNKS(status); 1066 + pcs->autoneg_complete = !!(status & BMSR_ANEGCOMPLETE); 1067 + pcs->link = !!(status & BMSR_LSTATUS); 1047 1068 1048 1069 if (!pcs->link || !pcs->autoneg_complete) 1049 1070 return; ··· 1052 1073 if (lpa < 0) 1053 1074 return; 1054 1075 1055 - switch (USXGMII_LPA_SPEED(lpa)) { 1056 - case USXGMII_SPEED_10: 1076 + switch (lpa & MDIO_USXGMII_SPD_MASK) { 1077 + case MDIO_USXGMII_10: 1057 1078 pcs->speed = SPEED_10; 1058 1079 break; 1059 - case USXGMII_SPEED_100: 1080 + case MDIO_USXGMII_100: 1060 1081 pcs->speed = SPEED_100; 1061 1082 break; 1062 - case USXGMII_SPEED_1000: 1083 + case MDIO_USXGMII_1000: 1063 1084 pcs->speed = SPEED_1000; 1064 1085 break; 1065 - case USXGMII_SPEED_2500: 1086 + case MDIO_USXGMII_2500: 1066 1087 pcs->speed = SPEED_2500; 1067 1088 break; 1068 1089 default: 1069 1090 break; 1070 1091 } 1071 1092 1072 - if (USXGMII_LPA_DUPLEX(lpa)) 1093 + if (lpa & MDIO_USXGMII_FULL_DUPLEX) 1073 1094 pcs->duplex = DUPLEX_FULL; 1074 1095 else 1075 1096 pcs->duplex = DUPLEX_HALF;
+3
drivers/net/ethernet/freescale/enetc/enetc_hw.h
··· 224 224 #define ENETC_PM0_MAXFRM 0x8014 225 225 #define ENETC_SET_TX_MTU(val) ((val) << 16) 226 226 #define ENETC_SET_MAXFRM(val) ((val) & 0xffff) 227 + 228 + #define ENETC_PM_IMDIO_BASE 0x8030 229 + 227 230 #define ENETC_PM0_IF_MODE 0x8300 228 231 #define ENETC_PMO_IFM_RG BIT(2) 229 232 #define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11))
+164 -24
drivers/net/ethernet/freescale/enetc/enetc_pf.c
··· 1 1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 2 /* Copyright 2017-2019 NXP */ 3 3 4 + #include <linux/mdio.h> 4 5 #include <linux/module.h> 5 6 #include <linux/fsl/enetc_mdio.h> 6 7 #include <linux/of_mdio.h> ··· 482 481 enetc_port_wr(hw, ENETC_PSIVLANFMR, ENETC_PSIVLANFMR_VS); 483 482 } 484 483 485 - static void enetc_configure_port_mac(struct enetc_hw *hw) 484 + static void enetc_configure_port_mac(struct enetc_hw *hw, 485 + phy_interface_t phy_mode) 486 486 { 487 487 enetc_port_wr(hw, ENETC_PM0_MAXFRM, 488 488 ENETC_SET_MAXFRM(ENETC_RX_MAXFRM_SIZE)); ··· 499 497 ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC | 500 498 ENETC_PM0_TX_EN | ENETC_PM0_RX_EN); 501 499 /* set auto-speed for RGMII */ 502 - if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG) 500 + if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG || 501 + phy_interface_mode_is_rgmii(phy_mode)) 503 502 enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO); 504 - if (enetc_global_rd(hw, ENETC_G_EPFBLPR(1)) == ENETC_G_EPFBLPR1_XGMII) 503 + 504 + if (phy_mode == PHY_INTERFACE_MODE_USXGMII) 505 505 enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); 506 506 } 507 507 ··· 527 523 528 524 enetc_configure_port_pmac(hw); 529 525 530 - enetc_configure_port_mac(hw); 526 + enetc_configure_port_mac(hw, pf->if_mode); 531 527 532 528 enetc_port_si_configure(pf->si); 533 529 ··· 779 775 mdiobus_unregister(pf->mdio); 780 776 } 781 777 782 - static int enetc_of_get_phy(struct enetc_ndev_priv *priv) 778 + static int enetc_of_get_phy(struct enetc_pf *pf) 783 779 { 784 - struct enetc_pf *pf = enetc_si_priv(priv->si); 785 - struct device_node *np = priv->dev->of_node; 780 + struct device *dev = &pf->si->pdev->dev; 781 + struct device_node *np = dev->of_node; 786 782 struct device_node *mdio_np; 787 783 int err; 788 784 789 - priv->phy_node = of_parse_phandle(np, "phy-handle", 0); 790 - if (!priv->phy_node) { 785 + pf->phy_node = of_parse_phandle(np, "phy-handle", 0); 786 + if (!pf->phy_node) { 791 787 if (!of_phy_is_fixed_link(np)) { 792 - dev_err(priv->dev, "PHY not specified\n"); 788 + dev_err(dev, "PHY not specified\n"); 793 789 return -ENODEV; 794 790 } 795 791 796 792 err = of_phy_register_fixed_link(np); 797 793 if (err < 0) { 798 - dev_err(priv->dev, "fixed link registration failed\n"); 794 + dev_err(dev, "fixed link registration failed\n"); 799 795 return err; 800 796 } 801 797 802 - priv->phy_node = of_node_get(np); 798 + pf->phy_node = of_node_get(np); 803 799 } 804 800 805 801 mdio_np = of_get_child_by_name(np, "mdio"); ··· 807 803 of_node_put(mdio_np); 808 804 err = enetc_mdio_probe(pf); 809 805 if (err) { 810 - of_node_put(priv->phy_node); 806 + of_node_put(pf->phy_node); 811 807 return err; 812 808 } 813 809 } 814 810 815 - err = of_get_phy_mode(np, &priv->if_mode); 811 + err = of_get_phy_mode(np, &pf->if_mode); 816 812 if (err) { 817 - dev_err(priv->dev, "missing phy type\n"); 818 - of_node_put(priv->phy_node); 813 + dev_err(dev, "missing phy type\n"); 814 + of_node_put(pf->phy_node); 819 815 if (of_phy_is_fixed_link(np)) 820 816 of_phy_deregister_fixed_link(np); 821 817 else ··· 827 823 return 0; 828 824 } 829 825 830 - static void enetc_of_put_phy(struct enetc_ndev_priv *priv) 826 + static void enetc_of_put_phy(struct enetc_pf *pf) 831 827 { 832 - struct device_node *np = priv->dev->of_node; 828 + struct device_node *np = pf->si->pdev->dev.of_node; 833 829 834 830 if (np && of_phy_is_fixed_link(np)) 835 831 of_phy_deregister_fixed_link(np); 836 - if (priv->phy_node) 837 - of_node_put(priv->phy_node); 832 + if (pf->phy_node) 833 + of_node_put(pf->phy_node); 834 + } 835 + 836 + static int enetc_imdio_init(struct enetc_pf *pf, bool is_c45) 837 + { 838 + struct device *dev = &pf->si->pdev->dev; 839 + struct enetc_mdio_priv *mdio_priv; 840 + struct phy_device *pcs; 841 + struct mii_bus *bus; 842 + int err; 843 + 844 + bus = mdiobus_alloc_size(sizeof(*mdio_priv)); 845 + if (!bus) 846 + return -ENOMEM; 847 + 848 + bus->name = "Freescale ENETC internal MDIO Bus"; 849 + bus->read = enetc_mdio_read; 850 + bus->write = enetc_mdio_write; 851 + bus->parent = dev; 852 + bus->phy_mask = ~0; 853 + mdio_priv = bus->priv; 854 + mdio_priv->hw = &pf->si->hw; 855 + mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE; 856 + snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev)); 857 + 858 + err = mdiobus_register(bus); 859 + if (err) { 860 + dev_err(dev, "cannot register internal MDIO bus (%d)\n", err); 861 + goto free_mdio_bus; 862 + } 863 + 864 + pcs = get_phy_device(bus, 0, is_c45); 865 + if (IS_ERR(pcs)) { 866 + err = PTR_ERR(pcs); 867 + dev_err(dev, "cannot get internal PCS PHY (%d)\n", err); 868 + goto unregister_mdiobus; 869 + } 870 + 871 + pf->imdio = bus; 872 + pf->pcs = pcs; 873 + 874 + return 0; 875 + 876 + unregister_mdiobus: 877 + mdiobus_unregister(bus); 878 + free_mdio_bus: 879 + mdiobus_free(bus); 880 + return err; 881 + } 882 + 883 + static void enetc_imdio_remove(struct enetc_pf *pf) 884 + { 885 + if (pf->pcs) 886 + put_device(&pf->pcs->mdio.dev); 887 + if (pf->imdio) { 888 + mdiobus_unregister(pf->imdio); 889 + mdiobus_free(pf->imdio); 890 + } 891 + } 892 + 893 + static void enetc_configure_sgmii(struct phy_device *pcs) 894 + { 895 + /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001 896 + * for the MAC PCS in order to acknowledge the AN. 897 + */ 898 + phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII | ADVERTISE_LPACK); 899 + 900 + phy_write(pcs, ENETC_PCS_IF_MODE, 901 + ENETC_PCS_IF_MODE_SGMII_EN | 902 + ENETC_PCS_IF_MODE_USE_SGMII_AN); 903 + 904 + /* Adjust link timer for SGMII */ 905 + phy_write(pcs, ENETC_PCS_LINK_TIMER1, ENETC_PCS_LINK_TIMER1_VAL); 906 + phy_write(pcs, ENETC_PCS_LINK_TIMER2, ENETC_PCS_LINK_TIMER2_VAL); 907 + 908 + phy_write(pcs, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE); 909 + } 910 + 911 + static void enetc_configure_2500basex(struct phy_device *pcs) 912 + { 913 + phy_write(pcs, ENETC_PCS_IF_MODE, 914 + ENETC_PCS_IF_MODE_SGMII_EN | 915 + ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500)); 916 + 917 + phy_write(pcs, MII_BMCR, BMCR_SPEED1000 | BMCR_FULLDPLX | BMCR_RESET); 918 + } 919 + 920 + static void enetc_configure_usxgmii(struct phy_device *pcs) 921 + { 922 + /* Configure device ability for the USXGMII Replicator */ 923 + phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE, 924 + ADVERTISE_SGMII | ADVERTISE_LPACK | 925 + MDIO_USXGMII_FULL_DUPLEX); 926 + 927 + /* Restart PCS AN */ 928 + phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_BMCR, 929 + BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART); 930 + } 931 + 932 + static int enetc_configure_serdes(struct enetc_ndev_priv *priv) 933 + { 934 + bool is_c45 = priv->if_mode == PHY_INTERFACE_MODE_USXGMII; 935 + struct enetc_pf *pf = enetc_si_priv(priv->si); 936 + int err; 937 + 938 + if (priv->if_mode != PHY_INTERFACE_MODE_SGMII && 939 + priv->if_mode != PHY_INTERFACE_MODE_2500BASEX && 940 + priv->if_mode != PHY_INTERFACE_MODE_USXGMII) 941 + return 0; 942 + 943 + err = enetc_imdio_init(pf, is_c45); 944 + if (err) 945 + return err; 946 + 947 + switch (priv->if_mode) { 948 + case PHY_INTERFACE_MODE_SGMII: 949 + enetc_configure_sgmii(pf->pcs); 950 + break; 951 + case PHY_INTERFACE_MODE_2500BASEX: 952 + enetc_configure_2500basex(pf->pcs); 953 + break; 954 + case PHY_INTERFACE_MODE_USXGMII: 955 + enetc_configure_usxgmii(pf->pcs); 956 + break; 957 + default: 958 + dev_err(&pf->si->pdev->dev, "Unsupported link mode %s\n", 959 + phy_modes(priv->if_mode)); 960 + } 961 + 962 + return 0; 838 963 } 839 964 840 965 static int enetc_pf_probe(struct pci_dev *pdev, ··· 997 864 pf->si = si; 998 865 pf->total_vfs = pci_sriov_get_totalvfs(pdev); 999 866 867 + err = enetc_of_get_phy(pf); 868 + if (err) 869 + dev_warn(&pdev->dev, "Fallback to PHY-less operation\n"); 870 + 1000 871 enetc_configure_port(pf); 1001 872 1002 873 enetc_get_si_caps(si); ··· 1015 878 enetc_pf_netdev_setup(si, ndev, &enetc_ndev_ops); 1016 879 1017 880 priv = netdev_priv(ndev); 881 + priv->phy_node = pf->phy_node; 882 + priv->if_mode = pf->if_mode; 1018 883 1019 884 enetc_init_si_rings_params(priv); 1020 885 ··· 1032 893 goto err_alloc_msix; 1033 894 } 1034 895 1035 - err = enetc_of_get_phy(priv); 896 + err = enetc_configure_serdes(priv); 1036 897 if (err) 1037 - dev_warn(&pdev->dev, "Fallback to PHY-less operation\n"); 898 + dev_warn(&pdev->dev, "Attempted SerDes config but failed\n"); 1038 899 1039 900 err = register_netdev(ndev); 1040 901 if (err) ··· 1045 906 return 0; 1046 907 1047 908 err_reg_netdev: 1048 - enetc_of_put_phy(priv); 1049 909 enetc_free_msix(priv); 1050 910 err_alloc_msix: 1051 911 enetc_free_si_resources(priv); ··· 1052 914 si->ndev = NULL; 1053 915 free_netdev(ndev); 1054 916 err_alloc_netdev: 917 + enetc_of_put_phy(pf); 1055 918 err_map_pf_space: 1056 919 enetc_pci_remove(pdev); 1057 920 ··· 1071 932 priv = netdev_priv(si->ndev); 1072 933 unregister_netdev(si->ndev); 1073 934 935 + enetc_imdio_remove(pf); 1074 936 enetc_mdio_remove(pf); 1075 - enetc_of_put_phy(priv); 937 + enetc_of_put_phy(pf); 1076 938 1077 939 enetc_free_msix(priv); 1078 940
+5
drivers/net/ethernet/freescale/enetc/enetc_pf.h
··· 44 44 DECLARE_BITMAP(active_vlans, VLAN_N_VID); 45 45 46 46 struct mii_bus *mdio; /* saved for cleanup */ 47 + struct mii_bus *imdio; 48 + struct phy_device *pcs; 49 + 50 + struct device_node *phy_node; 51 + phy_interface_t if_mode; 47 52 }; 48 53 49 54 int enetc_msg_psi_init(struct enetc_pf *pf);
+26
include/uapi/linux/mdio.h
··· 324 324 return MDIO_PHY_ID_C45 | (prtad << 5) | devad; 325 325 } 326 326 327 + /* UsxgmiiChannelInfo[15:0] for USXGMII in-band auto-negotiation.*/ 328 + #define MDIO_USXGMII_EEE_CLK_STP 0x0080 /* EEE clock stop supported */ 329 + #define MDIO_USXGMII_EEE 0x0100 /* EEE supported */ 330 + #define MDIO_USXGMII_SPD_MASK 0x0e00 /* USXGMII speed mask */ 331 + #define MDIO_USXGMII_FULL_DUPLEX 0x1000 /* USXGMII full duplex */ 332 + #define MDIO_USXGMII_DPX_SPD_MASK 0x1e00 /* USXGMII duplex and speed bits */ 333 + #define MDIO_USXGMII_10 0x0000 /* 10Mbps */ 334 + #define MDIO_USXGMII_10HALF 0x0000 /* 10Mbps half-duplex */ 335 + #define MDIO_USXGMII_10FULL 0x1000 /* 10Mbps full-duplex */ 336 + #define MDIO_USXGMII_100 0x0200 /* 100Mbps */ 337 + #define MDIO_USXGMII_100HALF 0x0200 /* 100Mbps half-duplex */ 338 + #define MDIO_USXGMII_100FULL 0x1200 /* 100Mbps full-duplex */ 339 + #define MDIO_USXGMII_1000 0x0400 /* 1000Mbps */ 340 + #define MDIO_USXGMII_1000HALF 0x0400 /* 1000Mbps half-duplex */ 341 + #define MDIO_USXGMII_1000FULL 0x1400 /* 1000Mbps full-duplex */ 342 + #define MDIO_USXGMII_10G 0x0600 /* 10Gbps */ 343 + #define MDIO_USXGMII_10GHALF 0x0600 /* 10Gbps half-duplex */ 344 + #define MDIO_USXGMII_10GFULL 0x1600 /* 10Gbps full-duplex */ 345 + #define MDIO_USXGMII_2500 0x0800 /* 2500Mbps */ 346 + #define MDIO_USXGMII_2500HALF 0x0800 /* 2500Mbps half-duplex */ 347 + #define MDIO_USXGMII_2500FULL 0x1800 /* 2500Mbps full-duplex */ 348 + #define MDIO_USXGMII_5000 0x0a00 /* 5000Mbps */ 349 + #define MDIO_USXGMII_5000HALF 0x0a00 /* 5000Mbps half-duplex */ 350 + #define MDIO_USXGMII_5000FULL 0x1a00 /* 5000Mbps full-duplex */ 351 + #define MDIO_USXGMII_LINK 0x8000 /* PHY link with copper-side partner */ 352 + 327 353 #endif /* _UAPI__LINUX_MDIO_H__ */