lantiq: clarify VG3503J name
[oweals/openwrt.git] / target / linux / mvebu / patches-4.9 / 407-net-phy-add-802.3-clause-45-support-to-phylib.patch
1 From: Russell King <rmk+kernel@armlinux.org.uk>
2 Date: Thu, 29 Dec 2016 11:03:09 +0000
3 Subject: [PATCH] net: phy: add 802.3 clause 45 support to phylib
4
5 Add generic helpers for 802.3 clause 45 PHYs for >= 10Gbps support.
6
7 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
8 ---
9  create mode 100644 drivers/net/phy/phy-c45.c
10
11 --- a/drivers/net/phy/Makefile
12 +++ b/drivers/net/phy/Makefile
13 @@ -1,7 +1,7 @@
14  # Makefile for Linux PHY drivers and MDIO bus drivers
15  
16  libphy-y                       := phy.o phy_device.o mdio_bus.o mdio_device.o \
17 -                                  phy-core.o
18 +                                  phy-c45.o phy-core.o
19  libphy-$(CONFIG_SWPHY)         += swphy.o
20  
21  obj-$(CONFIG_MDIO_BOARDINFO)   += mdio-boardinfo.o
22 --- /dev/null
23 +++ b/drivers/net/phy/phy-c45.c
24 @@ -0,0 +1,234 @@
25 +/*
26 + * Clause 45 PHY support
27 + */
28 +#include <linux/ethtool.h>
29 +#include <linux/export.h>
30 +#include <linux/mdio.h>
31 +#include <linux/mii.h>
32 +#include <linux/phy.h>
33 +
34 +/**
35 + * genphy_c45_setup_forced - configures a forced speed
36 + * @phydev: target phy_device struct
37 + */
38 +int genphy_c45_pma_setup_forced(struct phy_device *phydev)
39 +{
40 +       int ctrl1, ctrl2, ret;
41 +
42 +       /* Half duplex is not supported */
43 +       if (phydev->duplex != DUPLEX_FULL)
44 +               return -EINVAL;
45 +
46 +       ctrl1 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
47 +       if (ctrl1 < 0)
48 +               return ctrl1;
49 +
50 +       ctrl2 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2);
51 +       if (ctrl2 < 0)
52 +               return ctrl2;
53 +
54 +       ctrl1 &= ~MDIO_CTRL1_SPEEDSEL;
55 +       /* PMA/PMD type selection is 1.7.5:0 not 1.7.3:0.  See 45.2.1.6.1. */
56 +       ctrl2 &= ~(MDIO_PMA_CTRL2_TYPE | 0x30);
57 +
58 +       switch (phydev->speed) {
59 +       case SPEED_10:
60 +               ctrl2 |= MDIO_PMA_CTRL2_10BT;
61 +               break;
62 +       case SPEED_100:
63 +               ctrl1 |= MDIO_PMA_CTRL1_SPEED100;
64 +               ctrl2 |= MDIO_PMA_CTRL2_100BTX;
65 +               break;
66 +       case SPEED_1000:
67 +               ctrl1 |= MDIO_PMA_CTRL1_SPEED1000;
68 +               /* Assume 1000base-T */
69 +               ctrl2 |= MDIO_PMA_CTRL2_1000BT;
70 +               break;
71 +       case SPEED_10000:
72 +               ctrl1 |= MDIO_CTRL1_SPEED10G;
73 +               /* Assume 10Gbase-T */
74 +               ctrl2 |= MDIO_PMA_CTRL2_10GBT;
75 +               break;
76 +       default:
77 +               return -EINVAL;
78 +       }
79 +
80 +       ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, ctrl1);
81 +       if (ret < 0)
82 +               return ret;
83 +
84 +       return phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2, ctrl2);
85 +}
86 +EXPORT_SYMBOL_GPL(genphy_c45_pma_setup_forced);
87 +
88 +/**
89 + * genphy_c45_an_disable_aneg - disable auto-negotiation
90 + * @phydev: target phy_device struct
91 + *
92 + * Disable auto-negotiation in the Clause 45 PHY. The link parameters
93 + * parameters are controlled through the PMA/PMD MMD registers.
94 + *
95 + * Returns zero on success, negative errno code on failure.
96 + */
97 +int genphy_c45_an_disable_aneg(struct phy_device *phydev)
98 +{
99 +       int val;
100 +
101 +       val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
102 +       if (val < 0)
103 +               return val;
104 +
105 +       val &= ~(MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
106 +
107 +       return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, val);
108 +}
109 +EXPORT_SYMBOL_GPL(genphy_c45_an_disable_aneg);
110 +
111 +/**
112 + * genphy_c45_restart_aneg - Enable and restart auto-negotiation
113 + * @phydev: target phy_device struct
114 + *
115 + * This assumes that the auto-negotiation MMD is present.
116 + *
117 + * Enable and restart auto-negotiation.
118 + */
119 +int genphy_c45_restart_aneg(struct phy_device *phydev)
120 +{
121 +       int val;
122 +
123 +       val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
124 +       if (val < 0)
125 +               return val;
126 +
127 +       val |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;
128 +
129 +       return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, val);
130 +}
131 +EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg);
132 +
133 +/**
134 + * genphy_c45_aneg_done - return auto-negotiation complete status
135 + * @phydev: target phy_device struct
136 + *
137 + * This assumes that the auto-negotiation MMD is present.
138 + *
139 + * Reads the status register from the auto-negotiation MMD, returning:
140 + * - positive if auto-negotiation is complete
141 + * - negative errno code on error
142 + * - zero otherwise
143 + */
144 +int genphy_c45_aneg_done(struct phy_device *phydev)
145 +{
146 +       int val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
147 +
148 +       return val < 0 ? val : val & MDIO_AN_STAT1_COMPLETE ? 1 : 0;
149 +}
150 +EXPORT_SYMBOL_GPL(genphy_c45_aneg_done);
151 +
152 +/**
153 + * genphy_c45_read_link - read the overall link status from the MMDs
154 + * @phydev: target phy_device struct
155 + * @mmd_mask: MMDs to read status from
156 + *
157 + * Read the link status from the specified MMDs, and if they all indicate
158 + * that the link is up, return positive.  If an error is encountered,
159 + * a negative errno will be returned, otherwise zero.
160 + */
161 +int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask)
162 +{
163 +       int val, devad;
164 +       bool link = true;
165 +
166 +       while (mmd_mask) {
167 +               devad = __ffs(mmd_mask);
168 +               mmd_mask &= ~BIT(devad);
169 +
170 +               val = phy_read_mmd(phydev, devad, MDIO_STAT1);
171 +               if (val < 0)
172 +                       return val;
173 +
174 +               /* Read twice because link state is latched and a
175 +                * read moves the current state into the register
176 +                */
177 +               val = phy_read_mmd(phydev, devad, MDIO_STAT1);
178 +               if (val < 0)
179 +                       return val;
180 +
181 +               if (!(val & MDIO_STAT1_LSTATUS))
182 +                       link = false;
183 +       }
184 +
185 +       return link;
186 +}
187 +EXPORT_SYMBOL_GPL(genphy_c45_read_link);
188 +
189 +/**
190 + * genphy_c45_read_lpa - read the link partner advertisment and pause
191 + * @phydev: target phy_device struct
192 + *
193 + * Read the Clause 45 defined base (7.19) and 10G (7.33) status registers,
194 + * filling in the link partner advertisment, pause and asym_pause members
195 + * in @phydev.  This assumes that the auto-negotiation MMD is present, and
196 + * the backplane bit (7.48.0) is clear.  Clause 45 PHY drivers are expected
197 + * to fill in the remainder of the link partner advert from vendor registers.
198 + */
199 +int genphy_c45_read_lpa(struct phy_device *phydev)
200 +{
201 +       int val;
202 +
203 +       /* Read the link partner's base page advertisment */
204 +       val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA);
205 +       if (val < 0)
206 +               return val;
207 +
208 +       phydev->lp_advertising = mii_lpa_to_ethtool_lpa_t(val);
209 +       phydev->pause = val & LPA_PAUSE_CAP ? 1 : 0;
210 +       phydev->asym_pause = val & LPA_PAUSE_ASYM ? 1 : 0;
211 +
212 +       /* Read the link partner's 10G advertisment */
213 +       val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
214 +       if (val < 0)
215 +               return val;
216 +
217 +       if (val & MDIO_AN_10GBT_STAT_LP10G)
218 +               phydev->lp_advertising |= ADVERTISED_10000baseT_Full;
219 +
220 +       return 0;
221 +}
222 +EXPORT_SYMBOL_GPL(genphy_c45_read_lpa);
223 +
224 +/**
225 + * genphy_c45_read_pma - read link speed etc from PMA
226 + * @phydev: target phy_device struct
227 + */
228 +int genphy_c45_read_pma(struct phy_device *phydev)
229 +{
230 +       int val;
231 +
232 +       val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
233 +       if (val < 0)
234 +               return val;
235 +
236 +       switch (val & MDIO_CTRL1_SPEEDSEL) {
237 +       case 0:
238 +               phydev->speed = SPEED_10;
239 +               break;
240 +       case MDIO_PMA_CTRL1_SPEED100:
241 +               phydev->speed = SPEED_100;
242 +               break;
243 +       case MDIO_PMA_CTRL1_SPEED1000:
244 +               phydev->speed = SPEED_1000;
245 +               break;
246 +       case MDIO_CTRL1_SPEED10G:
247 +               phydev->speed = SPEED_10000;
248 +               break;
249 +       default:
250 +               phydev->speed = SPEED_UNKNOWN;
251 +               break;
252 +       }
253 +
254 +       phydev->duplex = DUPLEX_FULL;
255 +
256 +       return 0;
257 +}
258 +EXPORT_SYMBOL_GPL(genphy_c45_read_pma);
259 --- a/drivers/net/phy/phy_device.c
260 +++ b/drivers/net/phy/phy_device.c
261 @@ -1390,27 +1390,19 @@ EXPORT_SYMBOL(genphy_read_status);
262  
263  static int gen10g_read_status(struct phy_device *phydev)
264  {
265 -       int devad, reg;
266         u32 mmd_mask = phydev->c45_ids.devices_in_package;
267 -
268 -       phydev->link = 1;
269 +       int ret;
270  
271         /* For now just lie and say it's 10G all the time */
272         phydev->speed = SPEED_10000;
273         phydev->duplex = DUPLEX_FULL;
274  
275 -       for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) {
276 -               if (!(mmd_mask & 1))
277 -                       continue;
278 -
279 -               /* Read twice because link state is latched and a
280 -                * read moves the current state into the register
281 -                */
282 -               phy_read_mmd(phydev, devad, MDIO_STAT1);
283 -               reg = phy_read_mmd(phydev, devad, MDIO_STAT1);
284 -               if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
285 -                       phydev->link = 0;
286 -       }
287 +       /* Avoid reading the vendor MMDs */
288 +       mmd_mask &= ~(BIT(MDIO_MMD_VEND1) | BIT(MDIO_MMD_VEND2));
289 +
290 +       ret = genphy_c45_read_link(phydev, mmd_mask);
291 +
292 +       phydev->link = ret > 0 ? 1 : 0;
293  
294         return 0;
295  }
296 --- a/include/linux/phy.h
297 +++ b/include/linux/phy.h
298 @@ -807,6 +807,8 @@ static inline const char *phydev_name(co
299  void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
300         __printf(2, 3);
301  void phy_attached_info(struct phy_device *phydev);
302 +
303 +/* Clause 22 PHY */
304  int genphy_config_init(struct phy_device *phydev);
305  int genphy_setup_forced(struct phy_device *phydev);
306  int genphy_restart_aneg(struct phy_device *phydev);
307 @@ -817,6 +819,16 @@ int genphy_read_status(struct phy_device
308  int genphy_suspend(struct phy_device *phydev);
309  int genphy_resume(struct phy_device *phydev);
310  int genphy_soft_reset(struct phy_device *phydev);
311 +
312 +/* Clause 45 PHY */
313 +int genphy_c45_restart_aneg(struct phy_device *phydev);
314 +int genphy_c45_aneg_done(struct phy_device *phydev);
315 +int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask);
316 +int genphy_c45_read_lpa(struct phy_device *phydev);
317 +int genphy_c45_read_pma(struct phy_device *phydev);
318 +int genphy_c45_pma_setup_forced(struct phy_device *phydev);
319 +int genphy_c45_an_disable_aneg(struct phy_device *phydev);
320 +
321  void phy_driver_unregister(struct phy_driver *drv);
322  void phy_drivers_unregister(struct phy_driver *drv, int n);
323  int phy_driver_register(struct phy_driver *new_driver, struct module *owner);