1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * drivers/net/ethernet/ibm/emac/phy.c
4 *
5 * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
6 * Borrowed from sungem_phy.c, though I only kept the generic MII
7 * driver for now.
8 *
9 * This file should be shared with other drivers or eventually
10 * merged as the "low level" part of miilib
11 *
12 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
13 *                <benh@kernel.crashing.org>
14 *
15 * Based on the arch/ppc version of the driver:
16 *
17 * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
18 * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
19 *
20 */
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/types.h>
24#include <linux/netdevice.h>
25#include <linux/mii.h>
26#include <linux/ethtool.h>
27#include <linux/delay.h>
28
29#include "emac.h"
30#include "phy.h"
31
32#define phy_read _phy_read
33#define phy_write _phy_write
34
35static inline int _phy_read(struct mii_phy *phy, int reg)
36{
37	return phy->mdio_read(phy->dev, phy->address, reg);
38}
39
40static inline void _phy_write(struct mii_phy *phy, int reg, int val)
41{
42	phy->mdio_write(phy->dev, phy->address, reg, val);
43}
44
45static inline int gpcs_phy_read(struct mii_phy *phy, int reg)
46{
47	return phy->mdio_read(phy->dev, phy->gpcs_address, reg);
48}
49
50static inline void gpcs_phy_write(struct mii_phy *phy, int reg, int val)
51{
52	phy->mdio_write(phy->dev, phy->gpcs_address, reg, val);
53}
54
55int emac_mii_reset_phy(struct mii_phy *phy)
56{
57	int val;
58	int limit = 10000;
59
60	val = phy_read(phy, MII_BMCR);
61	val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
62	val |= BMCR_RESET;
63	phy_write(phy, MII_BMCR, val);
64
65	udelay(300);
66
67	while (--limit) {
68		val = phy_read(phy, MII_BMCR);
69		if (val >= 0 && (val & BMCR_RESET) == 0)
70			break;
71		udelay(10);
72	}
73	if ((val & BMCR_ISOLATE) && limit > 0)
74		phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
75
76	return limit <= 0;
77}
78
79int emac_mii_reset_gpcs(struct mii_phy *phy)
80{
81	int val;
82	int limit = 10000;
83
84	val = gpcs_phy_read(phy, MII_BMCR);
85	val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
86	val |= BMCR_RESET;
87	gpcs_phy_write(phy, MII_BMCR, val);
88
89	udelay(300);
90
91	while (--limit) {
92		val = gpcs_phy_read(phy, MII_BMCR);
93		if (val >= 0 && (val & BMCR_RESET) == 0)
94			break;
95		udelay(10);
96	}
97	if ((val & BMCR_ISOLATE) && limit > 0)
98		gpcs_phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
99
100	if (limit > 0 && phy->mode == PHY_INTERFACE_MODE_SGMII) {
101		/* Configure GPCS interface to recommended setting for SGMII */
102		gpcs_phy_write(phy, 0x04, 0x8120); /* AsymPause, FDX */
103		gpcs_phy_write(phy, 0x07, 0x2801); /* msg_pg, toggle */
104		gpcs_phy_write(phy, 0x00, 0x0140); /* 1Gbps, FDX     */
105	}
106
107	return limit <= 0;
108}
109
110static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
111{
112	int ctl, adv;
113
114	phy->autoneg = AUTONEG_ENABLE;
115	phy->speed = SPEED_10;
116	phy->duplex = DUPLEX_HALF;
117	phy->pause = phy->asym_pause = 0;
118	phy->advertising = advertise;
119
120	ctl = phy_read(phy, MII_BMCR);
121	if (ctl < 0)
122		return ctl;
123	ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
124
125	/* First clear the PHY */
126	phy_write(phy, MII_BMCR, ctl);
127
128	/* Setup standard advertise */
129	adv = phy_read(phy, MII_ADVERTISE);
130	if (adv < 0)
131		return adv;
132	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
133		 ADVERTISE_PAUSE_ASYM);
134	if (advertise & ADVERTISED_10baseT_Half)
135		adv |= ADVERTISE_10HALF;
136	if (advertise & ADVERTISED_10baseT_Full)
137		adv |= ADVERTISE_10FULL;
138	if (advertise & ADVERTISED_100baseT_Half)
139		adv |= ADVERTISE_100HALF;
140	if (advertise & ADVERTISED_100baseT_Full)
141		adv |= ADVERTISE_100FULL;
142	if (advertise & ADVERTISED_Pause)
143		adv |= ADVERTISE_PAUSE_CAP;
144	if (advertise & ADVERTISED_Asym_Pause)
145		adv |= ADVERTISE_PAUSE_ASYM;
146	phy_write(phy, MII_ADVERTISE, adv);
147
148	if (phy->features &
149	    (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
150		adv = phy_read(phy, MII_CTRL1000);
151		if (adv < 0)
152			return adv;
153		adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
154		if (advertise & ADVERTISED_1000baseT_Full)
155			adv |= ADVERTISE_1000FULL;
156		if (advertise & ADVERTISED_1000baseT_Half)
157			adv |= ADVERTISE_1000HALF;
158		phy_write(phy, MII_CTRL1000, adv);
159	}
160
161	/* Start/Restart aneg */
162	ctl = phy_read(phy, MII_BMCR);
163	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
164	phy_write(phy, MII_BMCR, ctl);
165
166	return 0;
167}
168
169static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
170{
171	int ctl;
172
173	phy->autoneg = AUTONEG_DISABLE;
174	phy->speed = speed;
175	phy->duplex = fd;
176	phy->pause = phy->asym_pause = 0;
177
178	ctl = phy_read(phy, MII_BMCR);
179	if (ctl < 0)
180		return ctl;
181	ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
182
183	/* First clear the PHY */
184	phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
185
186	/* Select speed & duplex */
187	switch (speed) {
188	case SPEED_10:
189		break;
190	case SPEED_100:
191		ctl |= BMCR_SPEED100;
192		break;
193	case SPEED_1000:
194		ctl |= BMCR_SPEED1000;
195		break;
196	default:
197		return -EINVAL;
198	}
199	if (fd == DUPLEX_FULL)
200		ctl |= BMCR_FULLDPLX;
201	phy_write(phy, MII_BMCR, ctl);
202
203	return 0;
204}
205
206static int genmii_poll_link(struct mii_phy *phy)
207{
208	int status;
209
210	/* Clear latched value with dummy read */
211	phy_read(phy, MII_BMSR);
212	status = phy_read(phy, MII_BMSR);
213	if (status < 0 || (status & BMSR_LSTATUS) == 0)
214		return 0;
215	if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
216		return 0;
217	return 1;
218}
219
220static int genmii_read_link(struct mii_phy *phy)
221{
222	if (phy->autoneg == AUTONEG_ENABLE) {
223		int glpa = 0;
224		int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
225		if (lpa < 0)
226			return lpa;
227
228		if (phy->features &
229		    (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
230			int adv = phy_read(phy, MII_CTRL1000);
231			glpa = phy_read(phy, MII_STAT1000);
232
233			if (glpa < 0 || adv < 0)
234				return adv;
235
236			glpa &= adv << 2;
237		}
238
239		phy->speed = SPEED_10;
240		phy->duplex = DUPLEX_HALF;
241		phy->pause = phy->asym_pause = 0;
242
243		if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
244			phy->speed = SPEED_1000;
245			if (glpa & LPA_1000FULL)
246				phy->duplex = DUPLEX_FULL;
247		} else if (lpa & (LPA_100FULL | LPA_100HALF)) {
248			phy->speed = SPEED_100;
249			if (lpa & LPA_100FULL)
250				phy->duplex = DUPLEX_FULL;
251		} else if (lpa & LPA_10FULL)
252			phy->duplex = DUPLEX_FULL;
253
254		if (phy->duplex == DUPLEX_FULL) {
255			phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
256			phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
257		}
258	} else {
259		int bmcr = phy_read(phy, MII_BMCR);
260		if (bmcr < 0)
261			return bmcr;
262
263		if (bmcr & BMCR_FULLDPLX)
264			phy->duplex = DUPLEX_FULL;
265		else
266			phy->duplex = DUPLEX_HALF;
267		if (bmcr & BMCR_SPEED1000)
268			phy->speed = SPEED_1000;
269		else if (bmcr & BMCR_SPEED100)
270			phy->speed = SPEED_100;
271		else
272			phy->speed = SPEED_10;
273
274		phy->pause = phy->asym_pause = 0;
275	}
276	return 0;
277}
278
279/* Generic implementation for most 10/100/1000 PHYs */
280static const struct mii_phy_ops generic_phy_ops = {
281	.setup_aneg	= genmii_setup_aneg,
282	.setup_forced	= genmii_setup_forced,
283	.poll_link	= genmii_poll_link,
284	.read_link	= genmii_read_link
285};
286
287static struct mii_phy_def genmii_phy_def = {
288	.phy_id		= 0x00000000,
289	.phy_id_mask	= 0x00000000,
290	.name		= "Generic MII",
291	.ops		= &generic_phy_ops
292};
293
294/* CIS8201 */
295#define MII_CIS8201_10BTCSR	0x16
296#define  TENBTCSR_ECHO_DISABLE	0x2000
297#define MII_CIS8201_EPCR	0x17
298#define  EPCR_MODE_MASK		0x3000
299#define  EPCR_GMII_MODE		0x0000
300#define  EPCR_RGMII_MODE	0x1000
301#define  EPCR_TBI_MODE		0x2000
302#define  EPCR_RTBI_MODE		0x3000
303#define MII_CIS8201_ACSR	0x1c
304#define  ACSR_PIN_PRIO_SELECT	0x0004
305
306static int cis8201_init(struct mii_phy *phy)
307{
308	int epcr;
309
310	epcr = phy_read(phy, MII_CIS8201_EPCR);
311	if (epcr < 0)
312		return epcr;
313
314	epcr &= ~EPCR_MODE_MASK;
315
316	switch (phy->mode) {
317	case PHY_INTERFACE_MODE_TBI:
318		epcr |= EPCR_TBI_MODE;
319		break;
320	case PHY_INTERFACE_MODE_RTBI:
321		epcr |= EPCR_RTBI_MODE;
322		break;
323	case PHY_INTERFACE_MODE_GMII:
324		epcr |= EPCR_GMII_MODE;
325		break;
326	case PHY_INTERFACE_MODE_RGMII:
327	default:
328		epcr |= EPCR_RGMII_MODE;
329	}
330
331	phy_write(phy, MII_CIS8201_EPCR, epcr);
332
333	/* MII regs override strap pins */
334	phy_write(phy, MII_CIS8201_ACSR,
335		  phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
336
337	/* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
338	phy_write(phy, MII_CIS8201_10BTCSR,
339		  phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
340
341	return 0;
342}
343
344static const struct mii_phy_ops cis8201_phy_ops = {
345	.init		= cis8201_init,
346	.setup_aneg	= genmii_setup_aneg,
347	.setup_forced	= genmii_setup_forced,
348	.poll_link	= genmii_poll_link,
349	.read_link	= genmii_read_link
350};
351
352static struct mii_phy_def cis8201_phy_def = {
353	.phy_id		= 0x000fc410,
354	.phy_id_mask	= 0x000ffff0,
355	.name		= "CIS8201 Gigabit Ethernet",
356	.ops		= &cis8201_phy_ops
357};
358
359static struct mii_phy_def bcm5248_phy_def = {
360
361	.phy_id		= 0x0143bc00,
362	.phy_id_mask	= 0x0ffffff0,
363	.name		= "BCM5248 10/100 SMII Ethernet",
364	.ops		= &generic_phy_ops
365};
366
367static int m88e1111_init(struct mii_phy *phy)
368{
369	pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__);
370	phy_write(phy, 0x14, 0x0ce3);
371	phy_write(phy, 0x18, 0x4101);
372	phy_write(phy, 0x09, 0x0e00);
373	phy_write(phy, 0x04, 0x01e1);
374	phy_write(phy, 0x00, 0x9140);
375	phy_write(phy, 0x00, 0x1140);
376
377	return  0;
378}
379
380static int m88e1112_init(struct mii_phy *phy)
381{
382	/*
383	 * Marvell 88E1112 PHY needs to have the SGMII MAC
384	 * interace (page 2) properly configured to
385	 * communicate with the 460EX/GT GPCS interface.
386	 */
387
388	u16 reg_short;
389
390	pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__);
391
392	/* Set access to Page 2 */
393	phy_write(phy, 0x16, 0x0002);
394
395	phy_write(phy, 0x00, 0x0040); /* 1Gbps */
396	reg_short = (u16)(phy_read(phy, 0x1a));
397	reg_short |= 0x8000; /* bypass Auto-Negotiation */
398	phy_write(phy, 0x1a, reg_short);
399	emac_mii_reset_phy(phy); /* reset MAC interface */
400
401	/* Reset access to Page 0 */
402	phy_write(phy, 0x16, 0x0000);
403
404	return  0;
405}
406
407static int et1011c_init(struct mii_phy *phy)
408{
409	u16 reg_short;
410
411	reg_short = (u16)(phy_read(phy, 0x16));
412	reg_short &= ~(0x7);
413	reg_short |= 0x6;	/* RGMII Trace Delay*/
414	phy_write(phy, 0x16, reg_short);
415
416	reg_short = (u16)(phy_read(phy, 0x17));
417	reg_short &= ~(0x40);
418	phy_write(phy, 0x17, reg_short);
419
420	phy_write(phy, 0x1c, 0x74f0);
421	return 0;
422}
423
424static const struct mii_phy_ops et1011c_phy_ops = {
425	.init		= et1011c_init,
426	.setup_aneg	= genmii_setup_aneg,
427	.setup_forced	= genmii_setup_forced,
428	.poll_link	= genmii_poll_link,
429	.read_link	= genmii_read_link
430};
431
432static struct mii_phy_def et1011c_phy_def = {
433	.phy_id		= 0x0282f000,
434	.phy_id_mask	= 0x0fffff00,
435	.name		= "ET1011C Gigabit Ethernet",
436	.ops		= &et1011c_phy_ops
437};
438
439
440
441
442
443static const struct mii_phy_ops m88e1111_phy_ops = {
444	.init		= m88e1111_init,
445	.setup_aneg	= genmii_setup_aneg,
446	.setup_forced	= genmii_setup_forced,
447	.poll_link	= genmii_poll_link,
448	.read_link	= genmii_read_link
449};
450
451static struct mii_phy_def m88e1111_phy_def = {
452
453	.phy_id		= 0x01410CC0,
454	.phy_id_mask	= 0x0ffffff0,
455	.name		= "Marvell 88E1111 Ethernet",
456	.ops		= &m88e1111_phy_ops,
457};
458
459static const struct mii_phy_ops m88e1112_phy_ops = {
460	.init		= m88e1112_init,
461	.setup_aneg	= genmii_setup_aneg,
462	.setup_forced	= genmii_setup_forced,
463	.poll_link	= genmii_poll_link,
464	.read_link	= genmii_read_link
465};
466
467static struct mii_phy_def m88e1112_phy_def = {
468	.phy_id		= 0x01410C90,
469	.phy_id_mask	= 0x0ffffff0,
470	.name		= "Marvell 88E1112 Ethernet",
471	.ops		= &m88e1112_phy_ops,
472};
473
474static int ar8035_init(struct mii_phy *phy)
475{
476	phy_write(phy, 0x1d, 0x5); /* Address debug register 5 */
477	phy_write(phy, 0x1e, 0x2d47); /* Value copied from u-boot */
478	phy_write(phy, 0x1d, 0xb);    /* Address hib ctrl */
479	phy_write(phy, 0x1e, 0xbc20); /* Value copied from u-boot */
480
481	return 0;
482}
483
484static const struct mii_phy_ops ar8035_phy_ops = {
485	.init		= ar8035_init,
486	.setup_aneg	= genmii_setup_aneg,
487	.setup_forced	= genmii_setup_forced,
488	.poll_link	= genmii_poll_link,
489	.read_link	= genmii_read_link,
490};
491
492static struct mii_phy_def ar8035_phy_def = {
493	.phy_id		= 0x004dd070,
494	.phy_id_mask	= 0xfffffff0,
495	.name		= "Atheros 8035 Gigabit Ethernet",
496	.ops		= &ar8035_phy_ops,
497};
498
499static struct mii_phy_def *mii_phy_table[] = {
500	&et1011c_phy_def,
501	&cis8201_phy_def,
502	&bcm5248_phy_def,
503	&m88e1111_phy_def,
504	&m88e1112_phy_def,
505	&ar8035_phy_def,
506	&genmii_phy_def,
507	NULL
508};
509
510int emac_mii_phy_probe(struct mii_phy *phy, int address)
511{
512	struct mii_phy_def *def;
513	int i;
514	u32 id;
515
516	phy->autoneg = AUTONEG_DISABLE;
517	phy->advertising = 0;
518	phy->address = address;
519	phy->speed = SPEED_10;
520	phy->duplex = DUPLEX_HALF;
521	phy->pause = phy->asym_pause = 0;
522
523	/* Take PHY out of isolate mode and reset it. */
524	if (emac_mii_reset_phy(phy))
525		return -ENODEV;
526
527	/* Read ID and find matching entry */
528	id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
529	for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
530		if ((id & def->phy_id_mask) == def->phy_id)
531			break;
532	/* Should never be NULL (we have a generic entry), but... */
533	if (!def)
534		return -ENODEV;
535
536	phy->def = def;
537
538	/* Determine PHY features if needed */
539	phy->features = def->features;
540	if (!phy->features) {
541		u16 bmsr = phy_read(phy, MII_BMSR);
542		if (bmsr & BMSR_ANEGCAPABLE)
543			phy->features |= SUPPORTED_Autoneg;
544		if (bmsr & BMSR_10HALF)
545			phy->features |= SUPPORTED_10baseT_Half;
546		if (bmsr & BMSR_10FULL)
547			phy->features |= SUPPORTED_10baseT_Full;
548		if (bmsr & BMSR_100HALF)
549			phy->features |= SUPPORTED_100baseT_Half;
550		if (bmsr & BMSR_100FULL)
551			phy->features |= SUPPORTED_100baseT_Full;
552		if (bmsr & BMSR_ESTATEN) {
553			u16 esr = phy_read(phy, MII_ESTATUS);
554			if (esr & ESTATUS_1000_TFULL)
555				phy->features |= SUPPORTED_1000baseT_Full;
556			if (esr & ESTATUS_1000_THALF)
557				phy->features |= SUPPORTED_1000baseT_Half;
558		}
559		phy->features |= SUPPORTED_MII;
560	}
561
562	/* Setup default advertising */
563	phy->advertising = phy->features;
564
565	return 0;
566}
567
568MODULE_LICENSE("GPL");
569