ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 701-net-0229-enetc-Initialize-SerDes-for-SGMII-and-SXGMII-protoco.patch
1 From 6943ed031ee75f13a950e293f92db68ea2ec2786 Mon Sep 17 00:00:00 2001
2 From: Claudiu Manoil <claudiu.manoil@nxp.com>
3 Date: Wed, 14 Aug 2019 14:34:47 +0300
4 Subject: [PATCH] enetc: Initialize SerDes for SGMII and SXGMII protocols
5
6 ENETC has ethernet MACs capable of SGMII and SXGMII but
7 in order to use these protocols some serdes configurations
8 need to be performed.
9 The serdes is configurable via an internal MDIO bus
10 connected to an internal PCS device, all reads/writes are
11 performed at address 0.
12 This patch basically removes the dependecy on a bootloader
13 regarding serdes initialization.
14
15 Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
16 Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
17 ---
18  drivers/net/ethernet/freescale/enetc/enetc_hw.h   | 17 +++++++
19  drivers/net/ethernet/freescale/enetc/enetc_mdio.c | 24 +++++++++
20  drivers/net/ethernet/freescale/enetc/enetc_pf.c   | 59 +++++++++++++++++++++++
21  drivers/net/ethernet/freescale/enetc/enetc_pf.h   |  2 +
22  4 files changed, 102 insertions(+)
23
24 --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h
25 +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h
26 @@ -221,6 +221,23 @@ enum enetc_bdr_type {TX, RX};
27  #define ENETC_PM0_MAXFRM       0x8014
28  #define ENETC_SET_TX_MTU(val)  ((val) << 16)
29  #define ENETC_SET_MAXFRM(val)  ((val) & 0xffff)
30 +
31 +#define ENETC_PM_IMDIO_BASE    0x8030
32 +/* PCS registers */
33 +#define ENETC_PCS_CR                   0x0
34 +#define ENETC_PCS_CR_RESET_AN          0x1200
35 +#define ENETC_PCS_CR_DEF_VAL           0x0140
36 +#define ENETC_PCS_CR_LANE_RESET                0x8000
37 +#define ENETC_PCS_DEV_ABILITY          0x04
38 +#define ENETC_PCS_DEV_ABILITY_SGMII    0x4001
39 +#define ENETC_PCS_DEV_ABILITY_SXGMII   0x5001
40 +#define ENETC_PCS_LINK_TIMER1          0x12
41 +#define ENETC_PCS_LINK_TIMER1_VAL      0x06a0
42 +#define ENETC_PCS_LINK_TIMER2          0x13
43 +#define ENETC_PCS_LINK_TIMER2_VAL      0x0003
44 +#define ENETC_PCS_IF_MODE              0x14
45 +#define ENETC_PCS_IF_MODE_SGMII_AN     0x0003
46 +
47  #define ENETC_PM0_IF_MODE      0x8300
48  #define ENETC_PMO_IFM_RG       BIT(2)
49  #define ENETC_PM0_IFM_RLP      (BIT(5) | BIT(11))
50 --- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c
51 +++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c
52 @@ -200,3 +200,27 @@ void enetc_mdio_remove(struct enetc_pf *
53         if (pf->mdio)
54                 mdiobus_unregister(pf->mdio);
55  }
56 +
57 +int enetc_imdio_init(struct enetc_pf *pf)
58 +{
59 +       struct device *dev = &pf->si->pdev->dev;
60 +       struct enetc_mdio_priv *mdio_priv;
61 +       struct mii_bus *bus;
62 +
63 +       bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv));
64 +       if (!bus)
65 +               return -ENOMEM;
66 +
67 +       bus->name = "FSL ENETC internal MDIO Bus";
68 +       bus->read = enetc_mdio_read;
69 +       bus->write = enetc_mdio_write;
70 +       bus->parent = dev;
71 +       mdio_priv = bus->priv;
72 +       mdio_priv->hw = &pf->si->hw;
73 +       mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE;
74 +       snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
75 +
76 +       pf->imdio = bus;
77 +
78 +       return 0;
79 +}
80 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
81 +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
82 @@ -807,6 +807,61 @@ static void enetc_of_put_phy(struct enet
83                 of_node_put(priv->phy_node);
84  }
85  
86 +static void enetc_configure_sgmii(struct mii_bus *imdio)
87 +{
88 +       /* Set to SGMII mode, use AN */
89 +       imdio->write(imdio, 0, ENETC_PCS_IF_MODE,
90 +                    ENETC_PCS_IF_MODE_SGMII_AN);
91 +
92 +       /* Dev ability - SGMII */
93 +       imdio->write(imdio, 0, ENETC_PCS_DEV_ABILITY,
94 +                    ENETC_PCS_DEV_ABILITY_SGMII);
95 +
96 +       /* Adjust link timer for SGMII */
97 +       imdio->write(imdio, 0, ENETC_PCS_LINK_TIMER1,
98 +                    ENETC_PCS_LINK_TIMER1_VAL);
99 +       imdio->write(imdio, 0, ENETC_PCS_LINK_TIMER2,
100 +                    ENETC_PCS_LINK_TIMER2_VAL);
101 +
102 +       /* restart PCS AN */
103 +       imdio->write(imdio, 0, ENETC_PCS_CR,
104 +                    ENETC_PCS_CR_RESET_AN | ENETC_PCS_CR_DEF_VAL);
105 +}
106 +
107 +static void enetc_configure_sxgmii(struct mii_bus *imdio)
108 +{
109 +       /* Dev ability - SXGMII */
110 +       imdio->write(imdio, 0, MII_ADDR_C45 | (MDIO_MMD_VEND2 << 16) |
111 +                    ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SXGMII);
112 +
113 +       /* Restart PCS AN */
114 +       imdio->write(imdio, 0, MII_ADDR_C45 | (MDIO_MMD_VEND2 << 16) |
115 +                    ENETC_PCS_CR,
116 +                    ENETC_PCS_CR_LANE_RESET | ENETC_PCS_CR_RESET_AN);
117 +}
118 +
119 +static int enetc_configure_serdes(struct enetc_ndev_priv *priv)
120 +{
121 +       struct enetc_pf *pf = enetc_si_priv(priv->si);
122 +       int err;
123 +
124 +       if (priv->if_mode != PHY_INTERFACE_MODE_SGMII &&
125 +           priv->if_mode != PHY_INTERFACE_MODE_XGMII)
126 +               return 0;
127 +
128 +       err = enetc_imdio_init(pf);
129 +       if (err)
130 +               return err;
131 +
132 +       if (priv->if_mode == PHY_INTERFACE_MODE_SGMII)
133 +               enetc_configure_sgmii(pf->imdio);
134 +
135 +       if (priv->if_mode == PHY_INTERFACE_MODE_XGMII)
136 +               enetc_configure_sxgmii(pf->imdio);
137 +
138 +       return 0;
139 +}
140 +
141  static int enetc_pf_probe(struct pci_dev *pdev,
142                           const struct pci_device_id *ent)
143  {
144 @@ -871,6 +926,10 @@ static int enetc_pf_probe(struct pci_dev
145         if (err)
146                 dev_warn(&pdev->dev, "Fallback to PHY-less operation\n");
147  
148 +       err = enetc_configure_serdes(priv);
149 +       if (err)
150 +               dev_warn(&pdev->dev, "Attempted serdes config but failed\n");
151 +
152         err = register_netdev(ndev);
153         if (err)
154                 goto err_reg_netdev;
155 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h
156 +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h
157 @@ -44,6 +44,7 @@ struct enetc_pf {
158         DECLARE_BITMAP(active_vlans, VLAN_N_VID);
159  
160         struct mii_bus *mdio; /* saved for cleanup */
161 +       struct mii_bus *imdio;
162  };
163  
164  int enetc_msg_psi_init(struct enetc_pf *pf);
165 @@ -53,3 +54,4 @@ void enetc_msg_handle_rxmsg(struct enetc
166  /* MDIO */
167  int enetc_mdio_probe(struct enetc_pf *pf);
168  void enetc_mdio_remove(struct enetc_pf *pf);
169 +int enetc_imdio_init(struct enetc_pf *pf);