xref: /openbmc/linux/drivers/net/phy/phy-c45.c (revision df687341)
1 /*
2  * Clause 45 PHY support
3  */
4 #include <linux/ethtool.h>
5 #include <linux/export.h>
6 #include <linux/mdio.h>
7 #include <linux/mii.h>
8 #include <linux/phy.h>
9 
10 /**
11  * genphy_c45_setup_forced - configures a forced speed
12  * @phydev: target phy_device struct
13  */
14 int genphy_c45_pma_setup_forced(struct phy_device *phydev)
15 {
16 	int ctrl1, ctrl2, ret;
17 
18 	/* Half duplex is not supported */
19 	if (phydev->duplex != DUPLEX_FULL)
20 		return -EINVAL;
21 
22 	ctrl1 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
23 	if (ctrl1 < 0)
24 		return ctrl1;
25 
26 	ctrl2 = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2);
27 	if (ctrl2 < 0)
28 		return ctrl2;
29 
30 	ctrl1 &= ~MDIO_CTRL1_SPEEDSEL;
31 	/*
32 	 * PMA/PMD type selection is 1.7.5:0 not 1.7.3:0.  See 45.2.1.6.1
33 	 * in 802.3-2012 and 802.3-2015.
34 	 */
35 	ctrl2 &= ~(MDIO_PMA_CTRL2_TYPE | 0x30);
36 
37 	switch (phydev->speed) {
38 	case SPEED_10:
39 		ctrl2 |= MDIO_PMA_CTRL2_10BT;
40 		break;
41 	case SPEED_100:
42 		ctrl1 |= MDIO_PMA_CTRL1_SPEED100;
43 		ctrl2 |= MDIO_PMA_CTRL2_100BTX;
44 		break;
45 	case SPEED_1000:
46 		ctrl1 |= MDIO_PMA_CTRL1_SPEED1000;
47 		/* Assume 1000base-T */
48 		ctrl2 |= MDIO_PMA_CTRL2_1000BT;
49 		break;
50 	case SPEED_10000:
51 		ctrl1 |= MDIO_CTRL1_SPEED10G;
52 		/* Assume 10Gbase-T */
53 		ctrl2 |= MDIO_PMA_CTRL2_10GBT;
54 		break;
55 	default:
56 		return -EINVAL;
57 	}
58 
59 	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1, ctrl1);
60 	if (ret < 0)
61 		return ret;
62 
63 	return phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL2, ctrl2);
64 }
65 EXPORT_SYMBOL_GPL(genphy_c45_pma_setup_forced);
66 
67 /**
68  * genphy_c45_an_disable_aneg - disable auto-negotiation
69  * @phydev: target phy_device struct
70  *
71  * Disable auto-negotiation in the Clause 45 PHY. The link parameters
72  * parameters are controlled through the PMA/PMD MMD registers.
73  *
74  * Returns zero on success, negative errno code on failure.
75  */
76 int genphy_c45_an_disable_aneg(struct phy_device *phydev)
77 {
78 	int val;
79 
80 	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
81 	if (val < 0)
82 		return val;
83 
84 	val &= ~(MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART);
85 
86 	return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, val);
87 }
88 EXPORT_SYMBOL_GPL(genphy_c45_an_disable_aneg);
89 
90 /**
91  * genphy_c45_restart_aneg - Enable and restart auto-negotiation
92  * @phydev: target phy_device struct
93  *
94  * This assumes that the auto-negotiation MMD is present.
95  *
96  * Enable and restart auto-negotiation.
97  */
98 int genphy_c45_restart_aneg(struct phy_device *phydev)
99 {
100 	int val;
101 
102 	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1);
103 	if (val < 0)
104 		return val;
105 
106 	val |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART;
107 
108 	return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, val);
109 }
110 EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg);
111 
112 /**
113  * genphy_c45_aneg_done - return auto-negotiation complete status
114  * @phydev: target phy_device struct
115  *
116  * This assumes that the auto-negotiation MMD is present.
117  *
118  * Reads the status register from the auto-negotiation MMD, returning:
119  * - positive if auto-negotiation is complete
120  * - negative errno code on error
121  * - zero otherwise
122  */
123 int genphy_c45_aneg_done(struct phy_device *phydev)
124 {
125 	int val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
126 
127 	return val < 0 ? val : val & MDIO_AN_STAT1_COMPLETE ? 1 : 0;
128 }
129 EXPORT_SYMBOL_GPL(genphy_c45_aneg_done);
130 
131 /**
132  * genphy_c45_read_link - read the overall link status from the MMDs
133  * @phydev: target phy_device struct
134  * @mmd_mask: MMDs to read status from
135  *
136  * Read the link status from the specified MMDs, and if they all indicate
137  * that the link is up, return positive.  If an error is encountered,
138  * a negative errno will be returned, otherwise zero.
139  */
140 int genphy_c45_read_link(struct phy_device *phydev, u32 mmd_mask)
141 {
142 	int val, devad;
143 	bool link = true;
144 
145 	while (mmd_mask) {
146 		devad = __ffs(mmd_mask);
147 		mmd_mask &= ~BIT(devad);
148 
149 		/* The link state is latched low so that momentary link
150 		 * drops can be detected.  Do not double-read the status
151 		 * register if the link is down.
152 		 */
153 		val = phy_read_mmd(phydev, devad, MDIO_STAT1);
154 		if (val < 0)
155 			return val;
156 
157 		if (!(val & MDIO_STAT1_LSTATUS))
158 			link = false;
159 	}
160 
161 	return link;
162 }
163 EXPORT_SYMBOL_GPL(genphy_c45_read_link);
164 
165 /**
166  * genphy_c45_read_lpa - read the link partner advertisement and pause
167  * @phydev: target phy_device struct
168  *
169  * Read the Clause 45 defined base (7.19) and 10G (7.33) status registers,
170  * filling in the link partner advertisement, pause and asym_pause members
171  * in @phydev.  This assumes that the auto-negotiation MMD is present, and
172  * the backplane bit (7.48.0) is clear.  Clause 45 PHY drivers are expected
173  * to fill in the remainder of the link partner advert from vendor registers.
174  */
175 int genphy_c45_read_lpa(struct phy_device *phydev)
176 {
177 	int val;
178 
179 	/* Read the link partner's base page advertisement */
180 	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_LPA);
181 	if (val < 0)
182 		return val;
183 
184 	mii_lpa_to_linkmode_lpa_t(phydev->lp_advertising, val);
185 	phydev->pause = val & LPA_PAUSE_CAP ? 1 : 0;
186 	phydev->asym_pause = val & LPA_PAUSE_ASYM ? 1 : 0;
187 
188 	/* Read the link partner's 10G advertisement */
189 	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
190 	if (val < 0)
191 		return val;
192 
193 	if (val & MDIO_AN_10GBT_STAT_LP10G)
194 		linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
195 				 phydev->lp_advertising);
196 
197 	return 0;
198 }
199 EXPORT_SYMBOL_GPL(genphy_c45_read_lpa);
200 
201 /**
202  * genphy_c45_read_pma - read link speed etc from PMA
203  * @phydev: target phy_device struct
204  */
205 int genphy_c45_read_pma(struct phy_device *phydev)
206 {
207 	int val;
208 
209 	val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1);
210 	if (val < 0)
211 		return val;
212 
213 	switch (val & MDIO_CTRL1_SPEEDSEL) {
214 	case 0:
215 		phydev->speed = SPEED_10;
216 		break;
217 	case MDIO_PMA_CTRL1_SPEED100:
218 		phydev->speed = SPEED_100;
219 		break;
220 	case MDIO_PMA_CTRL1_SPEED1000:
221 		phydev->speed = SPEED_1000;
222 		break;
223 	case MDIO_CTRL1_SPEED10G:
224 		phydev->speed = SPEED_10000;
225 		break;
226 	default:
227 		phydev->speed = SPEED_UNKNOWN;
228 		break;
229 	}
230 
231 	phydev->duplex = DUPLEX_FULL;
232 
233 	return 0;
234 }
235 EXPORT_SYMBOL_GPL(genphy_c45_read_pma);
236 
237 /**
238  * genphy_c45_read_mdix - read mdix status from PMA
239  * @phydev: target phy_device struct
240  */
241 int genphy_c45_read_mdix(struct phy_device *phydev)
242 {
243 	int val;
244 
245 	if (phydev->speed == SPEED_10000) {
246 		val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
247 				   MDIO_PMA_10GBT_SWAPPOL);
248 		if (val < 0)
249 			return val;
250 
251 		switch (val) {
252 		case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
253 			phydev->mdix = ETH_TP_MDI;
254 			break;
255 
256 		case 0:
257 			phydev->mdix = ETH_TP_MDI_X;
258 			break;
259 
260 		default:
261 			phydev->mdix = ETH_TP_MDI_INVALID;
262 			break;
263 		}
264 	}
265 
266 	return 0;
267 }
268 EXPORT_SYMBOL_GPL(genphy_c45_read_mdix);
269 
270 /* The gen10g_* functions are the old Clause 45 stub */
271 
272 int gen10g_config_aneg(struct phy_device *phydev)
273 {
274 	return 0;
275 }
276 EXPORT_SYMBOL_GPL(gen10g_config_aneg);
277 
278 int gen10g_read_status(struct phy_device *phydev)
279 {
280 	u32 mmd_mask = phydev->c45_ids.devices_in_package;
281 	int ret;
282 
283 	/* For now just lie and say it's 10G all the time */
284 	phydev->speed = SPEED_10000;
285 	phydev->duplex = DUPLEX_FULL;
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 EXPORT_SYMBOL_GPL(gen10g_read_status);
297 
298 int gen10g_no_soft_reset(struct phy_device *phydev)
299 {
300 	/* Do nothing for now */
301 	return 0;
302 }
303 EXPORT_SYMBOL_GPL(gen10g_no_soft_reset);
304 
305 int gen10g_config_init(struct phy_device *phydev)
306 {
307 	/* Temporarily just say we support everything */
308 	linkmode_zero(phydev->supported);
309 
310 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
311 			 phydev->supported);
312 	linkmode_copy(phydev->advertising, phydev->supported);
313 
314 	return 0;
315 }
316 EXPORT_SYMBOL_GPL(gen10g_config_init);
317 
318 int gen10g_suspend(struct phy_device *phydev)
319 {
320 	return 0;
321 }
322 EXPORT_SYMBOL_GPL(gen10g_suspend);
323 
324 int gen10g_resume(struct phy_device *phydev)
325 {
326 	return 0;
327 }
328 EXPORT_SYMBOL_GPL(gen10g_resume);
329 
330 struct phy_driver genphy_10g_driver = {
331 	.phy_id         = 0xffffffff,
332 	.phy_id_mask    = 0xffffffff,
333 	.name           = "Generic 10G PHY",
334 	.soft_reset	= gen10g_no_soft_reset,
335 	.config_init    = gen10g_config_init,
336 	.features       = PHY_10GBIT_FEATURES,
337 	.config_aneg    = gen10g_config_aneg,
338 	.read_status    = gen10g_read_status,
339 	.suspend        = gen10g_suspend,
340 	.resume         = gen10g_resume,
341 };
342