File Index
Files and directories
Sign in
FILE

smsc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/phy/smsc.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * drivers/net/phy/smsc.c
  4 *
  5 * Driver for SMSC PHYs
  6 *
  7 * Author: Herbert Valerio Riedel
  8 *
  9 * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
 10 *
 11 * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@shawell.net
 12 *
 13 */
 14
 15#include <linux/clk.h>
 16#include <linux/kernel.h>
 17#include <linux/module.h>
 18#include <linux/mii.h>
 19#include <linux/ethtool.h>
 20#include <linux/of.h>
 21#include <linux/phy.h>
 22#include <linux/netdevice.h>
 23#include <linux/crc16.h>
 24#include <linux/etherdevice.h>
 25#include <linux/smscphy.h>
 26
 27/* Vendor-specific PHY Definitions */
 28/* EDPD NLP / crossover time configuration */
 29#define PHY_EDPD_CONFIG			16
 30#define PHY_EDPD_CONFIG_EXT_CROSSOVER_	0x0001
 31
 32/* Control/Status Indication Register */
 33#define SPECIAL_CTRL_STS		27
 34#define SPECIAL_CTRL_STS_OVRRD_AMDIX_	0x8000
 35#define SPECIAL_CTRL_STS_AMDIX_ENABLE_	0x4000
 36#define SPECIAL_CTRL_STS_AMDIX_STATE_	0x2000
 37
 38#define EDPD_MAX_WAIT_DFLT_MS		640
 39/* interval between phylib state machine runs in ms */
 40#define PHY_STATE_MACH_MS		1000
 41
 42struct smsc_hw_stat {
 43	const char *string;
 44	u8 reg;
 45	u8 bits;
 46};
 47
 48static struct smsc_hw_stat smsc_hw_stats[] = {
 49	{ "phy_symbol_errors", 26, 16},
 50};
 51
 52struct smsc_phy_priv {
 53	unsigned int edpd_enable:1;
 54	unsigned int edpd_mode_set_by_user:1;
 55	unsigned int edpd_max_wait_ms;
 56	bool wol_arp;
 57};
 58
 59static int smsc_phy_ack_interrupt(struct phy_device *phydev)
 60{
 61	int rc = phy_read(phydev, MII_LAN83C185_ISF);
 62
 63	return rc < 0 ? rc : 0;
 64}
 65
 66int smsc_phy_config_intr(struct phy_device *phydev)
 67{
 68	int rc;
 69
 70	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
 71		rc = smsc_phy_ack_interrupt(phydev);
 72		if (rc)
 73			return rc;
 74
 75		rc = phy_write(phydev, MII_LAN83C185_IM,
 76			       MII_LAN83C185_ISF_INT_PHYLIB_EVENTS);
 77	} else {
 78		rc = phy_write(phydev, MII_LAN83C185_IM, 0);
 79		if (rc)
 80			return rc;
 81
 82		rc = smsc_phy_ack_interrupt(phydev);
 83	}
 84
 85	return rc < 0 ? rc : 0;
 86}
 87EXPORT_SYMBOL_GPL(smsc_phy_config_intr);
 88
 89static int smsc_phy_config_edpd(struct phy_device *phydev)
 90{
 91	struct smsc_phy_priv *priv = phydev->priv;
 92
 93	if (priv->edpd_enable)
 94		return phy_set_bits(phydev, MII_LAN83C185_CTRL_STATUS,
 95				    MII_LAN83C185_EDPWRDOWN);
 96	else
 97		return phy_clear_bits(phydev, MII_LAN83C185_CTRL_STATUS,
 98				      MII_LAN83C185_EDPWRDOWN);
 99}
100
101irqreturn_t smsc_phy_handle_interrupt(struct phy_device *phydev)
102{
103	int irq_status;
104
105	irq_status = phy_read(phydev, MII_LAN83C185_ISF);
106	if (irq_status < 0) {
107		if (irq_status != -ENODEV)
108			phy_error(phydev);
109
110		return IRQ_NONE;
111	}
112
113	if (!(irq_status & MII_LAN83C185_ISF_INT_PHYLIB_EVENTS))
114		return IRQ_NONE;
115
116	phy_trigger_machine(phydev);
117
118	return IRQ_HANDLED;
119}
120EXPORT_SYMBOL_GPL(smsc_phy_handle_interrupt);
121
122int smsc_phy_config_init(struct phy_device *phydev)
123{
124	struct smsc_phy_priv *priv = phydev->priv;
125
126	if (!priv)
127		return 0;
128
129	/* don't use EDPD in irq mode except overridden by user */
130	if (!priv->edpd_mode_set_by_user && phydev->irq != PHY_POLL)
131		priv->edpd_enable = false;
132
133	return smsc_phy_config_edpd(phydev);
134}
135EXPORT_SYMBOL_GPL(smsc_phy_config_init);
136
137static int smsc_phy_reset(struct phy_device *phydev)
138{
139	int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
140	if (rc < 0)
141		return rc;
142
143	/* If the SMSC PHY is in power down mode, then set it
144	 * in all capable mode before using it.
145	 */
146	if ((rc & MII_LAN83C185_MODE_MASK) == MII_LAN83C185_MODE_POWERDOWN) {
147		/* set "all capable" mode */
148		rc |= MII_LAN83C185_MODE_ALL;
149		phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
150	}
151
152	/* reset the phy */
153	return genphy_soft_reset(phydev);
154}
155
156static int lan87xx_config_aneg(struct phy_device *phydev)
157{
158	u8 mdix_ctrl;
159	int val;
160	int rc;
161
162	/* When auto-negotiation is disabled (forced mode), the PHY's
163	 * Auto-MDIX will continue toggling the TX/RX pairs.
164	 *
165	 * To establish a stable link, we must select a fixed MDI mode.
166	 * If the user has not specified a fixed MDI mode (i.e., mdix_ctrl is
167	 * 'auto'), we default to ETH_TP_MDI. This choice of a ETH_TP_MDI mode
168	 * mirrors the behavior the hardware would exhibit if the AUTOMDIX_EN
169	 * strap were configured for a fixed MDI connection.
170	 */
171	if (phydev->autoneg == AUTONEG_DISABLE) {
172		if (phydev->mdix_ctrl == ETH_TP_MDI_AUTO)
173			mdix_ctrl = ETH_TP_MDI;
174		else
175			mdix_ctrl = phydev->mdix_ctrl;
176	} else {
177		mdix_ctrl = phydev->mdix_ctrl;
178	}
179
180	switch (mdix_ctrl) {
181	case ETH_TP_MDI:
182		val = SPECIAL_CTRL_STS_OVRRD_AMDIX_;
183		break;
184	case ETH_TP_MDI_X:
185		val = SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
186			SPECIAL_CTRL_STS_AMDIX_STATE_;
187		break;
188	case ETH_TP_MDI_AUTO:
189		val = SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
190			SPECIAL_CTRL_STS_AMDIX_ENABLE_;
191		break;
192	default:
193		return genphy_config_aneg(phydev);
194	}
195
196	rc = phy_read(phydev, SPECIAL_CTRL_STS);
197	if (rc < 0)
198		return rc;
199
200	rc &= ~(SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
201		SPECIAL_CTRL_STS_AMDIX_ENABLE_ |
202		SPECIAL_CTRL_STS_AMDIX_STATE_);
203	rc |= val;
204	phy_write(phydev, SPECIAL_CTRL_STS, rc);
205
206	phydev->mdix = mdix_ctrl;
207	return genphy_config_aneg(phydev);
208}
209
210static int lan95xx_config_aneg_ext(struct phy_device *phydev)
211{
212	if (phydev->phy_id == 0x0007c0f0) { /* LAN9500A or LAN9505A */
213		/* Extend Manual AutoMDIX timer */
214		int rc = phy_set_bits(phydev, PHY_EDPD_CONFIG,
215				      PHY_EDPD_CONFIG_EXT_CROSSOVER_);
216
217		if (rc < 0)
218			return rc;
219	}
220
221	return lan87xx_config_aneg(phydev);
222}
223
224/*
225 * The LAN87xx suffers from rare absence of the ENERGYON-bit when Ethernet cable
226 * plugs in while LAN87xx is in Energy Detect Power-Down mode. This leads to
227 * unstable detection of plugging in Ethernet cable.
228 * This workaround disables Energy Detect Power-Down mode and waiting for
229 * response on link pulses to detect presence of plugged Ethernet cable.
230 * The Energy Detect Power-Down mode is enabled again in the end of procedure to
231 * save approximately 220 mW of power if cable is unplugged.
232 * The workaround is only applicable to poll mode. Energy Detect Power-Down may
233 * not be used in interrupt mode lest link change detection becomes unreliable.
234 */
235int lan87xx_read_status(struct phy_device *phydev)
236{
237	struct smsc_phy_priv *priv = phydev->priv;
238	int err;
239
240	err = genphy_read_status(phydev);
241	if (err)
242		return err;
243
244	if (!phydev->link && priv && priv->edpd_enable &&
245	    priv->edpd_max_wait_ms) {
246		unsigned int max_wait = priv->edpd_max_wait_ms * 1000;
247		int rc;
248
249		/* Disable EDPD to wake up PHY */
250		rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
251		if (rc < 0)
252			return rc;
253
254		rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
255			       rc & ~MII_LAN83C185_EDPWRDOWN);
256		if (rc < 0)
257			return rc;
258
259		/* Wait max 640 ms to detect energy and the timeout is not
260		 * an actual error.
261		 */
262		read_poll_timeout(phy_read, rc,
263				  rc & MII_LAN83C185_ENERGYON || rc < 0,
264				  10000, max_wait, true, phydev,
265				  MII_LAN83C185_CTRL_STATUS);
266		if (rc < 0)
267			return rc;
268
269		/* Re-enable EDPD */
270		rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
271		if (rc < 0)
272			return rc;
273
274		rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
275			       rc | MII_LAN83C185_EDPWRDOWN);
276		if (rc < 0)
277			return rc;
278	}
279
280	return err;
281}
282EXPORT_SYMBOL_GPL(lan87xx_read_status);
283
284static int lan87xx_phy_config_init(struct phy_device *phydev)
285{
286	int rc;
287
288	/* The LAN87xx PHY's initial MDI-X mode is determined by the AUTOMDIX_EN
289	 * hardware strap, but the driver cannot read the strap's status. This
290	 * creates an unpredictable initial state.
291	 *
292	 * To ensure consistent and reliable behavior across all boards,
293	 * override the strap configuration on initialization and force the PHY
294	 * into a known state with Auto-MDIX enabled, which is the expected
295	 * default for modern hardware.
296	 */
297	rc = phy_modify(phydev, SPECIAL_CTRL_STS,
298			SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
299			SPECIAL_CTRL_STS_AMDIX_ENABLE_ |
300			SPECIAL_CTRL_STS_AMDIX_STATE_,
301			SPECIAL_CTRL_STS_OVRRD_AMDIX_ |
302			SPECIAL_CTRL_STS_AMDIX_ENABLE_);
303	if (rc < 0)
304		return rc;
305
306	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
307
308	return smsc_phy_config_init(phydev);
309}
310
311static int lan874x_phy_config_init(struct phy_device *phydev)
312{
313	u16 val;
314	int rc;
315
316	/* Setup LED2/nINT/nPME pin to function as nPME.  May need user option
317	 * to use LED1/nINT/nPME.
318	 */
319	val = MII_LAN874X_PHY_PME2_SET;
320
321	/* The bits MII_LAN874X_PHY_WOL_PFDA_FR, MII_LAN874X_PHY_WOL_WUFR,
322	 * MII_LAN874X_PHY_WOL_MPR, and MII_LAN874X_PHY_WOL_BCAST_FR need to
323	 * be cleared to de-assert PME signal after a WoL event happens, but
324	 * using PME auto clear gets around that.
325	 */
326	val |= MII_LAN874X_PHY_PME_SELF_CLEAR;
327	rc = phy_write_mmd(phydev, MDIO_MMD_PCS, MII_LAN874X_PHY_MMD_WOL_WUCSR,
328			   val);
329	if (rc < 0)
330		return rc;
331
332	/* set nPME self clear delay time */
333	rc = phy_write_mmd(phydev, MDIO_MMD_PCS, MII_LAN874X_PHY_MMD_MCFGR,
334			   MII_LAN874X_PHY_PME_SELF_CLEAR_DELAY);
335	if (rc < 0)
336		return rc;
337
338	return smsc_phy_config_init(phydev);
339}
340
341static void lan874x_get_wol(struct phy_device *phydev,
342			    struct ethtool_wolinfo *wol)
343{
344	struct smsc_phy_priv *priv = phydev->priv;
345	int rc;
346
347	wol->supported = (WAKE_UCAST | WAKE_BCAST | WAKE_MAGIC |
348			  WAKE_ARP | WAKE_MCAST);
349	wol->wolopts = 0;
350
351	rc = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_LAN874X_PHY_MMD_WOL_WUCSR);
352	if (rc < 0)
353		return;
354
355	if (rc & MII_LAN874X_PHY_WOL_PFDAEN)
356		wol->wolopts |= WAKE_UCAST;
357
358	if (rc & MII_LAN874X_PHY_WOL_BCSTEN)
359		wol->wolopts |= WAKE_BCAST;
360
361	if (rc & MII_LAN874X_PHY_WOL_MPEN)
362		wol->wolopts |= WAKE_MAGIC;
363
364	if (rc & MII_LAN874X_PHY_WOL_WUEN) {
365		if (priv->wol_arp)
366			wol->wolopts |= WAKE_ARP;
367		else
368			wol->wolopts |= WAKE_MCAST;
369	}
370}
371
372static u16 smsc_crc16(const u8 *buffer, size_t len)
373{
374	return bitrev16(crc16(0xFFFF, buffer, len));
375}
376
377static int lan874x_chk_wol_pattern(const u8 pattern[], const u16 *mask,
378				   u8 len, u8 *data, u8 *datalen)
379{
380	size_t i, j, k;
381	int ret = 0;
382	u16 bits;
383
384	/* Pattern filtering can match up to 128 bytes of frame data.  There
385	 * are 8 registers to program the 16-bit masks, where each bit means
386	 * the byte will be compared.  The frame data will then go through a
387	 * CRC16 calculation for hardware comparison.  This helper function
388	 * makes sure only relevant frame data are included in this
389	 * calculation.  It provides a warning when the masks and expected
390	 * data size do not match.
391	 */
392	i = 0;
393	k = 0;
394	while (len > 0) {
395		bits = *mask;
396		for (j = 0; j < 16; j++, i++, len--) {
397			/* No more pattern. */
398			if (!len) {
399				/* The rest of bitmap is not empty. */
400				if (bits)
401					ret = i + 1;
402				break;
403			}
404			if (bits & 1)
405				data[k++] = pattern[i];
406			bits >>= 1;
407		}
408		mask++;
409	}
410	*datalen = k;
411	return ret;
412}
413
414static int lan874x_set_wol_pattern(struct phy_device *phydev, u16 val,
415				   const u8 data[], u8 datalen,
416				   const u16 *mask, u8 masklen)
417{
418	u16 crc, reg;
419	int rc;
420
421	/* Starting pattern offset is set before calling this function. */
422	val |= MII_LAN874X_PHY_WOL_FILTER_EN;
423	rc = phy_write_mmd(phydev, MDIO_MMD_PCS,
424			   MII_LAN874X_PHY_MMD_WOL_WUF_CFGA, val);
425	if (rc < 0)
426		return rc;
427
428	crc = smsc_crc16(data, datalen);
429	rc = phy_write_mmd(phydev, MDIO_MMD_PCS,
430			   MII_LAN874X_PHY_MMD_WOL_WUF_CFGB, crc);
431	if (rc < 0)
432		return rc;
433
434	masklen = (masklen + 15) & ~0xf;
435	reg = MII_LAN874X_PHY_MMD_WOL_WUF_MASK7;
436	while (masklen >= 16) {
437		rc = phy_write_mmd(phydev, MDIO_MMD_PCS, reg, *mask);
438		if (rc < 0)
439			return rc;
440		reg--;
441		mask++;
442		masklen -= 16;
443	}
444
445	/* Clear out the rest of mask registers. */
446	while (reg != MII_LAN874X_PHY_MMD_WOL_WUF_MASK0) {
447		phy_write_mmd(phydev, MDIO_MMD_PCS, reg, 0);
448		reg--;
449	}
450	return rc;
451}
452
453static int lan874x_set_wol(struct phy_device *phydev,
454			   struct ethtool_wolinfo *wol)
455{
456	struct net_device *ndev = phydev->attached_dev;
457	struct smsc_phy_priv *priv = phydev->priv;
458	u16 val, val_wucsr;
459	u8 data[128];
460	u8 datalen;
461	int rc;
462
463	/* lan874x has only one WoL filter pattern */
464	if ((wol->wolopts & (WAKE_ARP | WAKE_MCAST)) ==
465	    (WAKE_ARP | WAKE_MCAST)) {
466		phydev_info(phydev,
467			    "lan874x WoL supports one of ARP|MCAST at a time\n");
468		return -EOPNOTSUPP;
469	}
470
471	rc = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_LAN874X_PHY_MMD_WOL_WUCSR);
472	if (rc < 0)
473		return rc;
474
475	val_wucsr = rc;
476
477	if (wol->wolopts & WAKE_UCAST)
478		val_wucsr |= MII_LAN874X_PHY_WOL_PFDAEN;
479	else
480		val_wucsr &= ~MII_LAN874X_PHY_WOL_PFDAEN;
481
482	if (wol->wolopts & WAKE_BCAST)
483		val_wucsr |= MII_LAN874X_PHY_WOL_BCSTEN;
484	else
485		val_wucsr &= ~MII_LAN874X_PHY_WOL_BCSTEN;
486
487	if (wol->wolopts & WAKE_MAGIC)
488		val_wucsr |= MII_LAN874X_PHY_WOL_MPEN;
489	else
490		val_wucsr &= ~MII_LAN874X_PHY_WOL_MPEN;
491
492	/* Need to use pattern matching */
493	if (wol->wolopts & (WAKE_ARP | WAKE_MCAST))
494		val_wucsr |= MII_LAN874X_PHY_WOL_WUEN;
495	else
496		val_wucsr &= ~MII_LAN874X_PHY_WOL_WUEN;
497
498	if (wol->wolopts & WAKE_ARP) {
499		const u8 pattern[2] = { 0x08, 0x06 };
500		const u16 mask[1] = { 0x0003 };
501
502		rc = lan874x_chk_wol_pattern(pattern, mask, 2, data,
503					     &datalen);
504		if (rc)
505			phydev_dbg(phydev, "pattern not valid at %d\n", rc);
506
507		/* Need to match broadcast destination address and provided
508		 * data pattern at offset 12.
509		 */
510		val = 12 | MII_LAN874X_PHY_WOL_FILTER_BCSTEN;
511		rc = lan874x_set_wol_pattern(phydev, val, data, datalen, mask,
512					     2);
513		if (rc < 0)
514			return rc;
515		priv->wol_arp = true;
516	}
517
518	if (wol->wolopts & WAKE_MCAST) {
519		/* Need to match multicast destination address. */
520		val = MII_LAN874X_PHY_WOL_FILTER_MCASTTEN;
521		rc = lan874x_set_wol_pattern(phydev, val, data, 0, NULL, 0);
522		if (rc < 0)
523			return rc;
524		priv->wol_arp = false;
525	}
526
527	if (wol->wolopts & (WAKE_MAGIC | WAKE_UCAST)) {
528		const u8 *mac = (const u8 *)ndev->dev_addr;
529		int i, reg;
530
531		reg = MII_LAN874X_PHY_MMD_WOL_RX_ADDRC;
532		for (i = 0; i < 6; i += 2, reg--) {
533			rc = phy_write_mmd(phydev, MDIO_MMD_PCS, reg,
534					   ((mac[i + 1] << 8) | mac[i]));
535			if (rc < 0)
536				return rc;
537		}
538	}
539
540	rc = phy_write_mmd(phydev, MDIO_MMD_PCS, MII_LAN874X_PHY_MMD_WOL_WUCSR,
541			   val_wucsr);
542	if (rc < 0)
543		return rc;
544
545	return 0;
546}
547
548static int smsc_get_sset_count(struct phy_device *phydev)
549{
550	return ARRAY_SIZE(smsc_hw_stats);
551}
552
553static void smsc_get_strings(struct phy_device *phydev, u8 *data)
554{
555	int i;
556
557	for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++)
558		ethtool_puts(&data, smsc_hw_stats[i].string);
559}
560
561static u64 smsc_get_stat(struct phy_device *phydev, int i)
562{
563	struct smsc_hw_stat stat = smsc_hw_stats[i];
564	int val;
565	u64 ret;
566
567	val = phy_read(phydev, stat.reg);
568	if (val < 0)
569		ret = U64_MAX;
570	else
571		ret = val;
572
573	return ret;
574}
575
576static void smsc_get_stats(struct phy_device *phydev,
577			   struct ethtool_stats *stats, u64 *data)
578{
579	int i;
580
581	for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++)
582		data[i] = smsc_get_stat(phydev, i);
583}
584
585static int smsc_phy_get_edpd(struct phy_device *phydev, u16 *edpd)
586{
587	struct smsc_phy_priv *priv = phydev->priv;
588
589	if (!priv)
590		return -EOPNOTSUPP;
591
592	if (!priv->edpd_enable)
593		*edpd = ETHTOOL_PHY_EDPD_DISABLE;
594	else if (!priv->edpd_max_wait_ms)
595		*edpd = ETHTOOL_PHY_EDPD_NO_TX;
596	else
597		*edpd = PHY_STATE_MACH_MS + priv->edpd_max_wait_ms;
598
599	return 0;
600}
601
602static int smsc_phy_set_edpd(struct phy_device *phydev, u16 edpd)
603{
604	struct smsc_phy_priv *priv = phydev->priv;
605
606	if (!priv)
607		return -EOPNOTSUPP;
608
609	switch (edpd) {
610	case ETHTOOL_PHY_EDPD_DISABLE:
611		priv->edpd_enable = false;
612		break;
613	case ETHTOOL_PHY_EDPD_NO_TX:
614		priv->edpd_enable = true;
615		priv->edpd_max_wait_ms = 0;
616		break;
617	case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
618		edpd = PHY_STATE_MACH_MS + EDPD_MAX_WAIT_DFLT_MS;
619		fallthrough;
620	default:
621		if (phydev->irq != PHY_POLL)
622			return -EOPNOTSUPP;
623		if (edpd < PHY_STATE_MACH_MS || edpd > PHY_STATE_MACH_MS + 1000)
624			return -EINVAL;
625		priv->edpd_enable = true;
626		priv->edpd_max_wait_ms = edpd - PHY_STATE_MACH_MS;
627	}
628
629	priv->edpd_mode_set_by_user = true;
630
631	return smsc_phy_config_edpd(phydev);
632}
633
634int smsc_phy_get_tunable(struct phy_device *phydev,
635			 struct ethtool_tunable *tuna, void *data)
636{
637	switch (tuna->id) {
638	case ETHTOOL_PHY_EDPD:
639		return smsc_phy_get_edpd(phydev, data);
640	default:
641		return -EOPNOTSUPP;
642	}
643}
644EXPORT_SYMBOL_GPL(smsc_phy_get_tunable);
645
646int smsc_phy_set_tunable(struct phy_device *phydev,
647			 struct ethtool_tunable *tuna, const void *data)
648{
649	switch (tuna->id) {
650	case ETHTOOL_PHY_EDPD:
651		return smsc_phy_set_edpd(phydev, *(u16 *)data);
652	default:
653		return -EOPNOTSUPP;
654	}
655}
656EXPORT_SYMBOL_GPL(smsc_phy_set_tunable);
657
658int smsc_phy_probe(struct phy_device *phydev)
659{
660	struct device *dev = &phydev->mdio.dev;
661	struct smsc_phy_priv *priv;
662	struct clk *refclk;
663
664	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
665	if (!priv)
666		return -ENOMEM;
667
668	priv->edpd_enable = true;
669	priv->edpd_max_wait_ms = EDPD_MAX_WAIT_DFLT_MS;
670
671	if (device_property_present(dev, "smsc,disable-energy-detect"))
672		priv->edpd_enable = false;
673
674	phydev->priv = priv;
675
676	/* Make clk optional to keep DTB backward compatibility. */
677	refclk = devm_clk_get_optional_enabled_with_rate(dev, NULL,
678							 50 * 1000 * 1000);
679	if (IS_ERR(refclk))
680		return dev_err_probe(dev, PTR_ERR(refclk),
681				     "Failed to request clock\n");
682
683	return 0;
684}
685EXPORT_SYMBOL_GPL(smsc_phy_probe);
686
687static struct phy_driver smsc_phy_driver[] = {
688{
689	.phy_id		= 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
690	.phy_id_mask	= 0xfffffff0,
691	.name		= "SMSC LAN83C185",
692
693	/* PHY_BASIC_FEATURES */
694
695	.probe		= smsc_phy_probe,
696
697	/* basic functions */
698	.config_init	= smsc_phy_config_init,
699	.soft_reset	= smsc_phy_reset,
700
701	/* IRQ related */
702	.config_intr	= smsc_phy_config_intr,
703	.handle_interrupt = smsc_phy_handle_interrupt,
704
705	.suspend	= genphy_suspend,
706	.resume		= genphy_resume,
707}, {
708	.phy_id		= 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
709	.phy_id_mask	= 0xfffffff0,
710	.name		= "SMSC LAN8187",
711
712	/* PHY_BASIC_FEATURES */
713
714	.probe		= smsc_phy_probe,
715
716	/* basic functions */
717	.config_init	= smsc_phy_config_init,
718	.soft_reset	= smsc_phy_reset,
719
720	/* IRQ related */
721	.config_intr	= smsc_phy_config_intr,
722	.handle_interrupt = smsc_phy_handle_interrupt,
723
724	/* Statistics */
725	.get_sset_count = smsc_get_sset_count,
726	.get_strings	= smsc_get_strings,
727	.get_stats	= smsc_get_stats,
728
729	.suspend	= genphy_suspend,
730	.resume		= genphy_resume,
731}, {
732	/* This covers internal PHY (phy_id: 0x0007C0C3) for
733	 * LAN9500 (PID: 0x9500), LAN9514 (PID: 0xec00), LAN9505 (PID: 0x9505)
734	 */
735	.phy_id		= 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
736	.phy_id_mask	= 0xfffffff0,
737	.name		= "SMSC LAN8700",
738
739	/* PHY_BASIC_FEATURES */
740
741	.probe		= smsc_phy_probe,
742
743	/* basic functions */
744	.read_status	= lan87xx_read_status,
745	.config_init	= lan87xx_phy_config_init,
746	.soft_reset	= smsc_phy_reset,
747	.config_aneg	= lan87xx_config_aneg,
748
749	/* IRQ related */
750	.config_intr	= smsc_phy_config_intr,
751	.handle_interrupt = smsc_phy_handle_interrupt,
752
753	/* Statistics */
754	.get_sset_count = smsc_get_sset_count,
755	.get_strings	= smsc_get_strings,
756	.get_stats	= smsc_get_stats,
757
758	.get_tunable	= smsc_phy_get_tunable,
759	.set_tunable	= smsc_phy_set_tunable,
760
761	.suspend	= genphy_suspend,
762	.resume		= genphy_resume,
763}, {
764	.phy_id		= 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
765	.phy_id_mask	= 0xfffffff0,
766	.name		= "SMSC LAN911x Internal PHY",
767
768	/* PHY_BASIC_FEATURES */
769
770	.probe		= smsc_phy_probe,
771
772	/* IRQ related */
773	.config_intr	= smsc_phy_config_intr,
774	.handle_interrupt = smsc_phy_handle_interrupt,
775
776	.suspend	= genphy_suspend,
777	.resume		= genphy_resume,
778}, {
779	/* This covers internal PHY (phy_id: 0x0007C0F0) for
780	 * LAN9500A (PID: 0x9E00), LAN9505A (PID: 0x9E01)
781	 */
782	.phy_id		= 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
783	.phy_id_mask	= 0xfffffff0,
784	.name		= "SMSC LAN8710/LAN8720",
785
786	/* PHY_BASIC_FEATURES */
787
788	.flags		= PHY_RST_AFTER_CLK_EN,
789	.probe		= smsc_phy_probe,
790
791	/* basic functions */
792	.read_status	= lan87xx_read_status,
793	.config_init	= smsc_phy_config_init,
794	.soft_reset	= smsc_phy_reset,
795	.config_aneg	= lan95xx_config_aneg_ext,
796
797	/* IRQ related */
798	.config_intr	= smsc_phy_config_intr,
799	.handle_interrupt = smsc_phy_handle_interrupt,
800
801	/* Statistics */
802	.get_sset_count = smsc_get_sset_count,
803	.get_strings	= smsc_get_strings,
804	.get_stats	= smsc_get_stats,
805
806	.get_tunable	= smsc_phy_get_tunable,
807	.set_tunable	= smsc_phy_set_tunable,
808
809	.suspend	= genphy_suspend,
810	.resume		= genphy_resume,
811}, {
812	.phy_id		= 0x0007c110,
813	.phy_id_mask	= 0xfffffff0,
814	.name		= "SMSC LAN8740",
815
816	/* PHY_BASIC_FEATURES */
817	.flags		= PHY_RST_AFTER_CLK_EN,
818
819	.probe		= smsc_phy_probe,
820
821	/* basic functions */
822	.read_status	= lan87xx_read_status,
823	.config_init	= lan874x_phy_config_init,
824	.soft_reset	= smsc_phy_reset,
825
826	/* IRQ related */
827	.config_intr	= smsc_phy_config_intr,
828	.handle_interrupt = smsc_phy_handle_interrupt,
829
830	/* Statistics */
831	.get_sset_count = smsc_get_sset_count,
832	.get_strings	= smsc_get_strings,
833	.get_stats	= smsc_get_stats,
834
835	.get_tunable	= smsc_phy_get_tunable,
836	.set_tunable	= smsc_phy_set_tunable,
837
838	/* WoL */
839	.set_wol	= lan874x_set_wol,
840	.get_wol	= lan874x_get_wol,
841
842	.suspend	= genphy_suspend,
843	.resume		= genphy_resume,
844}, {
845	.phy_id		= 0x0007c130,	/* 0x0007c130 and 0x0007c131 */
846	/* This mask (0xfffffff2) is to differentiate from
847	 * LAN88xx (phy_id 0x0007c132)
848	 * and allows future phy_id revisions.
849	 */
850	.phy_id_mask	= 0xfffffff2,
851	.name		= "Microchip LAN8742",
852
853	/* PHY_BASIC_FEATURES */
854	.flags		= PHY_RST_AFTER_CLK_EN,
855
856	.probe		= smsc_phy_probe,
857
858	/* basic functions */
859	.read_status	= lan87xx_read_status,
860	.config_init	= lan874x_phy_config_init,
861	.soft_reset	= smsc_phy_reset,
862
863	/* IRQ related */
864	.config_intr	= smsc_phy_config_intr,
865	.handle_interrupt = smsc_phy_handle_interrupt,
866
867	/* Statistics */
868	.get_sset_count = smsc_get_sset_count,
869	.get_strings	= smsc_get_strings,
870	.get_stats	= smsc_get_stats,
871
872	.get_tunable	= smsc_phy_get_tunable,
873	.set_tunable	= smsc_phy_set_tunable,
874
875	/* WoL */
876	.set_wol	= lan874x_set_wol,
877	.get_wol	= lan874x_get_wol,
878
879	.suspend	= genphy_suspend,
880	.resume		= genphy_resume,
881} };
882
883module_phy_driver(smsc_phy_driver);
884
885MODULE_DESCRIPTION("SMSC PHY driver");
886MODULE_AUTHOR("Herbert Valerio Riedel");
887MODULE_LICENSE("GPL");
888
889static const struct mdio_device_id __maybe_unused smsc_tbl[] = {
890	{ 0x0007c0a0, 0xfffffff0 },
891	{ 0x0007c0b0, 0xfffffff0 },
892	{ 0x0007c0c0, 0xfffffff0 },
893	{ 0x0007c0d0, 0xfffffff0 },
894	{ 0x0007c0f0, 0xfffffff0 },
895	{ 0x0007c110, 0xfffffff0 },
896	{ 0x0007c130, 0xfffffff2 },
897	{ }
898};
899
900MODULE_DEVICE_TABLE(mdio, smsc_tbl);
~/ Read-only file preview.