1c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel/*
2c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel * drivers/net/phy/smsc.c
3c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel *
4c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel * Driver for SMSC PHYs
5c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel *
6c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel * Author: Herbert Valerio Riedel
7c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel *
8c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
9c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel *
10c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel * This program is free software; you can redistribute  it and/or modify it
11c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel * under  the terms of  the GNU General  Public License as published by the
12c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel * Free Software Foundation;  either version 2 of the  License, or (at your
13c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel * option) any later version.
14c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel *
154d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@smsc.com
164d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning *
17c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel */
18c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
19c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel#include <linux/kernel.h>
20c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel#include <linux/module.h>
21c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel#include <linux/mii.h>
22c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel#include <linux/ethtool.h>
23c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel#include <linux/phy.h>
24c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel#include <linux/netdevice.h>
2543c6759e73907e4c8e6624f70f5c4a860518b203Javier Martinez Canillas#include <linux/smscphy.h>
26c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
2748c41b9941233a85ccdb88c579bd4e9b0ee609cfSteve Glendinningstatic int smsc_phy_config_intr(struct phy_device *phydev)
28c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel{
29c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	int rc = phy_write (phydev, MII_LAN83C185_IM,
30c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel			((PHY_INTERRUPT_ENABLED == phydev->interrupts)
31c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel			? MII_LAN83C185_ISF_INT_PHYLIB_EVENTS
32c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel			: 0));
33c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
34c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	return rc < 0 ? rc : 0;
35c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel}
36c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
3748c41b9941233a85ccdb88c579bd4e9b0ee609cfSteve Glendinningstatic int smsc_phy_ack_interrupt(struct phy_device *phydev)
38c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel{
39c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	int rc = phy_read (phydev, MII_LAN83C185_ISF);
40c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
41c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	return rc < 0 ? rc : 0;
42c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel}
43c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
4448c41b9941233a85ccdb88c579bd4e9b0ee609cfSteve Glendinningstatic int smsc_phy_config_init(struct phy_device *phydev)
45c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel{
46698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro	int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
47698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro	if (rc < 0)
48698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro		return rc;
49698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro
50698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro	/* Enable energy detect mode for this SMSC Transceivers */
51698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro	rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
52698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro		       rc | MII_LAN83C185_EDPWRDOWN);
53698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro	if (rc < 0)
54698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro		return rc;
55698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro
5648c41b9941233a85ccdb88c579bd4e9b0ee609cfSteve Glendinning	return smsc_phy_ack_interrupt (phydev);
57c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel}
58c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
59698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallarostatic int lan911x_config_init(struct phy_device *phydev)
60698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro{
61698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro	return smsc_phy_ack_interrupt(phydev);
62698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro}
63c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
64c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedelstatic struct phy_driver lan83c185_driver = {
65c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	.phy_id		= 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
66c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	.phy_id_mask	= 0xfffffff0,
67c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	.name		= "SMSC LAN83C185",
68c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
69c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
70c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel				| SUPPORTED_Asym_Pause),
71c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
72c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
73c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	/* basic functions */
74c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	.config_aneg	= genphy_config_aneg,
75c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	.read_status	= genphy_read_status,
7648c41b9941233a85ccdb88c579bd4e9b0ee609cfSteve Glendinning	.config_init	= smsc_phy_config_init,
77c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
78c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	/* IRQ related */
7948c41b9941233a85ccdb88c579bd4e9b0ee609cfSteve Glendinning	.ack_interrupt	= smsc_phy_ack_interrupt,
8048c41b9941233a85ccdb88c579bd4e9b0ee609cfSteve Glendinning	.config_intr	= smsc_phy_config_intr,
81c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
82c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning	.suspend	= genphy_suspend,
83c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning	.resume		= genphy_resume,
84c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning
85c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	.driver		= { .owner = THIS_MODULE, }
86c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel};
87c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
884d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinningstatic struct phy_driver lan8187_driver = {
894d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.phy_id		= 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
904d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.phy_id_mask	= 0xfffffff0,
914d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.name		= "SMSC LAN8187",
924d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
934d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
944d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning				| SUPPORTED_Asym_Pause),
954d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
964d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
974d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	/* basic functions */
984d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.config_aneg	= genphy_config_aneg,
994d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.read_status	= genphy_read_status,
1004d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.config_init	= smsc_phy_config_init,
1014d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
1024d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	/* IRQ related */
1034d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.ack_interrupt	= smsc_phy_ack_interrupt,
1044d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.config_intr	= smsc_phy_config_intr,
1054d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
106c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning	.suspend	= genphy_suspend,
107c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning	.resume		= genphy_resume,
108c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning
1094d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.driver		= { .owner = THIS_MODULE, }
1104d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning};
1114d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
1124d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinningstatic struct phy_driver lan8700_driver = {
1134d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.phy_id		= 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
1144d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.phy_id_mask	= 0xfffffff0,
1154d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.name		= "SMSC LAN8700",
1164d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
1174d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
1184d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning				| SUPPORTED_Asym_Pause),
1194d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
1204d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
1214d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	/* basic functions */
1224d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.config_aneg	= genphy_config_aneg,
1234d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.read_status	= genphy_read_status,
1244d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.config_init	= smsc_phy_config_init,
1254d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
1264d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	/* IRQ related */
1274d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.ack_interrupt	= smsc_phy_ack_interrupt,
1284d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.config_intr	= smsc_phy_config_intr,
1294d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
130c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning	.suspend	= genphy_suspend,
131c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning	.resume		= genphy_resume,
132c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning
1334d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	.driver		= { .owner = THIS_MODULE, }
1344d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning};
1354d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
136fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinningstatic struct phy_driver lan911x_int_driver = {
137fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.phy_id		= 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
138fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.phy_id_mask	= 0xfffffff0,
139fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.name		= "SMSC LAN911x Internal PHY",
140fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning
141fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
142fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning				| SUPPORTED_Asym_Pause),
143fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
144fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning
145fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	/* basic functions */
146fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.config_aneg	= genphy_config_aneg,
147fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.read_status	= genphy_read_status,
148698244ace8b63896565022143ab19f141bc48993Giuseppe Cavallaro	.config_init	= lan911x_config_init,
149fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning
150fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	/* IRQ related */
151fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.ack_interrupt	= smsc_phy_ack_interrupt,
152fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.config_intr	= smsc_phy_config_intr,
153fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning
154c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning	.suspend	= genphy_suspend,
155c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning	.resume		= genphy_resume,
156c64d2a9afbccd0aecb122d108770a407fe7b7e3fSteve Glendinning
157fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	.driver		= { .owner = THIS_MODULE, }
158fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning};
159fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning
160e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinningstatic struct phy_driver lan8710_driver = {
161e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.phy_id		= 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
162e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.phy_id_mask	= 0xfffffff0,
163e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.name		= "SMSC LAN8710/LAN8720",
164e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning
165e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
166e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning				| SUPPORTED_Asym_Pause),
167e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.flags		= PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
168e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning
169e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	/* basic functions */
170e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.config_aneg	= genphy_config_aneg,
171e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.read_status	= genphy_read_status,
172e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.config_init	= smsc_phy_config_init,
173e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning
174e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	/* IRQ related */
175e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.ack_interrupt	= smsc_phy_ack_interrupt,
176e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.config_intr	= smsc_phy_config_intr,
177e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning
178e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.suspend	= genphy_suspend,
179e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.resume		= genphy_resume,
180e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning
181e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	.driver		= { .owner = THIS_MODULE, }
182e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning};
183e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning
184c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedelstatic int __init smsc_init(void)
185c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel{
1864d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	int ret;
1874d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
1884d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	ret = phy_driver_register (&lan83c185_driver);
1894d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	if (ret)
1904d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning		goto err1;
1914d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
1924d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	ret = phy_driver_register (&lan8187_driver);
1934d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	if (ret)
1944d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning		goto err2;
1954d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
1964d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	ret = phy_driver_register (&lan8700_driver);
1974d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	if (ret)
1984d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning		goto err3;
1994d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
200fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	ret = phy_driver_register (&lan911x_int_driver);
201fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	if (ret)
202fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning		goto err4;
203fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning
204e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	ret = phy_driver_register (&lan8710_driver);
205e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	if (ret)
206e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning		goto err5;
207e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning
2084d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	return 0;
2094d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning
210e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinningerr5:
211e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	phy_driver_unregister (&lan911x_int_driver);
212fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinningerr4:
213fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	phy_driver_unregister (&lan8700_driver);
2144d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinningerr3:
2154d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	phy_driver_unregister (&lan8187_driver);
2164d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinningerr2:
2174d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	phy_driver_unregister (&lan83c185_driver);
2184d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinningerr1:
2194d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	return ret;
220c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel}
221c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
222c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedelstatic void __exit smsc_exit(void)
223c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel{
224e072b639dc13b06b65be487633dad9bb3d2067d5Steve Glendinning	phy_driver_unregister (&lan8710_driver);
225fd9abb3d97c2ab883e4732ec1214fe64190236e7Steve Glendinning	phy_driver_unregister (&lan911x_int_driver);
2264d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	phy_driver_unregister (&lan8700_driver);
2274d9b1a022a33c57ca8f31a1364cef682c8c817d6Steve Glendinning	phy_driver_unregister (&lan8187_driver);
228c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel	phy_driver_unregister (&lan83c185_driver);
229c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel}
230c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
231c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio RiedelMODULE_DESCRIPTION("SMSC PHY driver");
232c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio RiedelMODULE_AUTHOR("Herbert Valerio Riedel");
233c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio RiedelMODULE_LICENSE("GPL");
234c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedel
235c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedelmodule_init(smsc_init);
236c9e055ac4fdbb52622437e0dbfdbc1d4897d2775Herbert Valerio Riedelmodule_exit(smsc_exit);
2374e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse
238cf93c94581bab447a5634c6d737c1cf38c080261Uwe Kleine-Königstatic struct mdio_device_id __maybe_unused smsc_tbl[] = {
2394e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse	{ 0x0007c0a0, 0xfffffff0 },
2404e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse	{ 0x0007c0b0, 0xfffffff0 },
2414e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse	{ 0x0007c0c0, 0xfffffff0 },
2424e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse	{ 0x0007c0d0, 0xfffffff0 },
2434e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse	{ 0x0007c0f0, 0xfffffff0 },
2444e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse	{ }
2454e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse};
2464e4f10f6498bc5038c0a110b5f21682fcb5578d7David Woodhouse
2474e4f10f6498bc5038c0a110b5f21682fcb5578d7David WoodhouseMODULE_DEVICE_TABLE(mdio, smsc_tbl);
248