aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/Kconfig5
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/amd.c8
-rw-r--r--drivers/net/phy/bcm63xx.c31
-rw-r--r--drivers/net/phy/bcm87xx.c231
-rw-r--r--drivers/net/phy/broadcom.c119
-rw-r--r--drivers/net/phy/cicada.c35
-rw-r--r--drivers/net/phy/davicom.c41
-rw-r--r--drivers/net/phy/dp83640.c23
-rw-r--r--drivers/net/phy/fixed.c4
-rw-r--r--drivers/net/phy/icplus.c31
-rw-r--r--drivers/net/phy/lxt.c47
-rw-r--r--drivers/net/phy/marvell.c22
-rw-r--r--drivers/net/phy/mdio_bus.c14
-rw-r--r--drivers/net/phy/micrel.c62
-rw-r--r--drivers/net/phy/national.c8
-rw-r--r--drivers/net/phy/phy.c316
-rw-r--r--drivers/net/phy/phy_device.c139
-rw-r--r--drivers/net/phy/realtek.c6
-rw-r--r--drivers/net/phy/smsc.c66
-rw-r--r--drivers/net/phy/spi_ks8995.c4
-rw-r--r--drivers/net/phy/ste10Xp.c21
-rw-r--r--drivers/net/phy/vitesse.c52
23 files changed, 824 insertions, 462 deletions
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 944cdfb80fe4..3090dc65a6f1 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -67,6 +67,11 @@ config BCM63XX_PHY
67 ---help--- 67 ---help---
68 Currently supports the 6348 and 6358 PHYs. 68 Currently supports the 6348 and 6358 PHYs.
69 69
70config BCM87XX_PHY
71 tristate "Driver for Broadcom BCM8706 and BCM8727 PHYs"
72 help
73 Currently supports the BCM8706 and BCM8727 10G Ethernet PHYs.
74
70config ICPLUS_PHY 75config ICPLUS_PHY
71 tristate "Drivers for ICPlus PHYs" 76 tristate "Drivers for ICPlus PHYs"
72 ---help--- 77 ---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index f51af688ef8b..6d2dc6c94f2e 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SMSC_PHY) += smsc.o
12obj-$(CONFIG_VITESSE_PHY) += vitesse.o 12obj-$(CONFIG_VITESSE_PHY) += vitesse.o
13obj-$(CONFIG_BROADCOM_PHY) += broadcom.o 13obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
14obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o 14obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o
15obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o
15obj-$(CONFIG_ICPLUS_PHY) += icplus.o 16obj-$(CONFIG_ICPLUS_PHY) += icplus.o
16obj-$(CONFIG_REALTEK_PHY) += realtek.o 17obj-$(CONFIG_REALTEK_PHY) += realtek.o
17obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o 18obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
diff --git a/drivers/net/phy/amd.c b/drivers/net/phy/amd.c
index cfabd5fe5372..a3fb5ceb6487 100644
--- a/drivers/net/phy/amd.c
+++ b/drivers/net/phy/amd.c
@@ -77,13 +77,7 @@ static struct phy_driver am79c_driver = {
77 77
78static int __init am79c_init(void) 78static int __init am79c_init(void)
79{ 79{
80 int ret; 80 return phy_driver_register(&am79c_driver);
81
82 ret = phy_driver_register(&am79c_driver);
83 if (ret)
84 return ret;
85
86 return 0;
87} 81}
88 82
89static void __exit am79c_exit(void) 83static void __exit am79c_exit(void)
diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
index cd802eb25fd2..84c7a39b1c65 100644
--- a/drivers/net/phy/bcm63xx.c
+++ b/drivers/net/phy/bcm63xx.c
@@ -71,7 +71,8 @@ static int bcm63xx_config_intr(struct phy_device *phydev)
71 return err; 71 return err;
72} 72}
73 73
74static struct phy_driver bcm63xx_1_driver = { 74static struct phy_driver bcm63xx_driver[] = {
75{
75 .phy_id = 0x00406000, 76 .phy_id = 0x00406000,
76 .phy_id_mask = 0xfffffc00, 77 .phy_id_mask = 0xfffffc00,
77 .name = "Broadcom BCM63XX (1)", 78 .name = "Broadcom BCM63XX (1)",
@@ -84,10 +85,8 @@ static struct phy_driver bcm63xx_1_driver = {
84 .ack_interrupt = bcm63xx_ack_interrupt, 85 .ack_interrupt = bcm63xx_ack_interrupt,
85 .config_intr = bcm63xx_config_intr, 86 .config_intr = bcm63xx_config_intr,
86 .driver = { .owner = THIS_MODULE }, 87 .driver = { .owner = THIS_MODULE },
87}; 88}, {
88 89 /* same phy as above, with just a different OUI */
89/* same phy as above, with just a different OUI */
90static struct phy_driver bcm63xx_2_driver = {
91 .phy_id = 0x002bdc00, 90 .phy_id = 0x002bdc00,
92 .phy_id_mask = 0xfffffc00, 91 .phy_id_mask = 0xfffffc00,
93 .name = "Broadcom BCM63XX (2)", 92 .name = "Broadcom BCM63XX (2)",
@@ -99,30 +98,18 @@ static struct phy_driver bcm63xx_2_driver = {
99 .ack_interrupt = bcm63xx_ack_interrupt, 98 .ack_interrupt = bcm63xx_ack_interrupt,
100 .config_intr = bcm63xx_config_intr, 99 .config_intr = bcm63xx_config_intr,
101 .driver = { .owner = THIS_MODULE }, 100 .driver = { .owner = THIS_MODULE },
102}; 101} };
103 102
104static int __init bcm63xx_phy_init(void) 103static int __init bcm63xx_phy_init(void)
105{ 104{
106 int ret; 105 return phy_drivers_register(bcm63xx_driver,
107 106 ARRAY_SIZE(bcm63xx_driver));
108 ret = phy_driver_register(&bcm63xx_1_driver);
109 if (ret)
110 goto out_63xx_1;
111 ret = phy_driver_register(&bcm63xx_2_driver);
112 if (ret)
113 goto out_63xx_2;
114 return ret;
115
116out_63xx_2:
117 phy_driver_unregister(&bcm63xx_1_driver);
118out_63xx_1:
119 return ret;
120} 107}
121 108
122static void __exit bcm63xx_phy_exit(void) 109static void __exit bcm63xx_phy_exit(void)
123{ 110{
124 phy_driver_unregister(&bcm63xx_1_driver); 111 phy_drivers_unregister(bcm63xx_driver,
125 phy_driver_unregister(&bcm63xx_2_driver); 112 ARRAY_SIZE(bcm63xx_driver));
126} 113}
127 114
128module_init(bcm63xx_phy_init); 115module_init(bcm63xx_phy_init);
diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c
new file mode 100644
index 000000000000..2346b38b9837
--- /dev/null
+++ b/drivers/net/phy/bcm87xx.c
@@ -0,0 +1,231 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2011 - 2012 Cavium, Inc.
7 */
8
9#include <linux/module.h>
10#include <linux/phy.h>
11#include <linux/of.h>
12
13#define PHY_ID_BCM8706 0x0143bdc1
14#define PHY_ID_BCM8727 0x0143bff0
15
16#define BCM87XX_PMD_RX_SIGNAL_DETECT (MII_ADDR_C45 | 0x1000a)
17#define BCM87XX_10GBASER_PCS_STATUS (MII_ADDR_C45 | 0x30020)
18#define BCM87XX_XGXS_LANE_STATUS (MII_ADDR_C45 | 0x40018)
19
20#define BCM87XX_LASI_CONTROL (MII_ADDR_C45 | 0x39002)
21#define BCM87XX_LASI_STATUS (MII_ADDR_C45 | 0x39005)
22
23#if IS_ENABLED(CONFIG_OF_MDIO)
24/* Set and/or override some configuration registers based on the
25 * broadcom,c45-reg-init property stored in the of_node for the phydev.
26 *
27 * broadcom,c45-reg-init = <devid reg mask value>,...;
28 *
29 * There may be one or more sets of <devid reg mask value>:
30 *
31 * devid: which sub-device to use.
32 * reg: the register.
33 * mask: if non-zero, ANDed with existing register value.
34 * value: ORed with the masked value and written to the regiser.
35 *
36 */
37static int bcm87xx_of_reg_init(struct phy_device *phydev)
38{
39 const __be32 *paddr;
40 const __be32 *paddr_end;
41 int len, ret;
42
43 if (!phydev->dev.of_node)
44 return 0;
45
46 paddr = of_get_property(phydev->dev.of_node,
47 "broadcom,c45-reg-init", &len);
48 if (!paddr)
49 return 0;
50
51 paddr_end = paddr + (len /= sizeof(*paddr));
52
53 ret = 0;
54
55 while (paddr + 3 < paddr_end) {
56 u16 devid = be32_to_cpup(paddr++);
57 u16 reg = be32_to_cpup(paddr++);
58 u16 mask = be32_to_cpup(paddr++);
59 u16 val_bits = be32_to_cpup(paddr++);
60 int val;
61 u32 regnum = MII_ADDR_C45 | (devid << 16) | reg;
62 val = 0;
63 if (mask) {
64 val = phy_read(phydev, regnum);
65 if (val < 0) {
66 ret = val;
67 goto err;
68 }
69 val &= mask;
70 }
71 val |= val_bits;
72
73 ret = phy_write(phydev, regnum, val);
74 if (ret < 0)
75 goto err;
76 }
77err:
78 return ret;
79}
80#else
81static int bcm87xx_of_reg_init(struct phy_device *phydev)
82{
83 return 0;
84}
85#endif /* CONFIG_OF_MDIO */
86
87static int bcm87xx_config_init(struct phy_device *phydev)
88{
89 phydev->supported = SUPPORTED_10000baseR_FEC;
90 phydev->advertising = ADVERTISED_10000baseR_FEC;
91 phydev->state = PHY_NOLINK;
92 phydev->autoneg = AUTONEG_DISABLE;
93
94 bcm87xx_of_reg_init(phydev);
95
96 return 0;
97}
98
99static int bcm87xx_config_aneg(struct phy_device *phydev)
100{
101 return -EINVAL;
102}
103
104static int bcm87xx_read_status(struct phy_device *phydev)
105{
106 int rx_signal_detect;
107 int pcs_status;
108 int xgxs_lane_status;
109
110 rx_signal_detect = phy_read(phydev, BCM87XX_PMD_RX_SIGNAL_DETECT);
111 if (rx_signal_detect < 0)
112 return rx_signal_detect;
113
114 if ((rx_signal_detect & 1) == 0)
115 goto no_link;
116
117 pcs_status = phy_read(phydev, BCM87XX_10GBASER_PCS_STATUS);
118 if (pcs_status < 0)
119 return pcs_status;
120
121 if ((pcs_status & 1) == 0)
122 goto no_link;
123
124 xgxs_lane_status = phy_read(phydev, BCM87XX_XGXS_LANE_STATUS);
125 if (xgxs_lane_status < 0)
126 return xgxs_lane_status;
127
128 if ((xgxs_lane_status & 0x1000) == 0)
129 goto no_link;
130
131 phydev->speed = 10000;
132 phydev->link = 1;
133 phydev->duplex = 1;
134 return 0;
135
136no_link:
137 phydev->link = 0;
138 return 0;
139}
140
141static int bcm87xx_config_intr(struct phy_device *phydev)
142{
143 int reg, err;
144
145 reg = phy_read(phydev, BCM87XX_LASI_CONTROL);
146
147 if (reg < 0)
148 return reg;
149
150 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
151 reg |= 1;
152 else
153 reg &= ~1;
154
155 err = phy_write(phydev, BCM87XX_LASI_CONTROL, reg);
156 return err;
157}
158
159static int bcm87xx_did_interrupt(struct phy_device *phydev)
160{
161 int reg;
162
163 reg = phy_read(phydev, BCM87XX_LASI_STATUS);
164
165 if (reg < 0) {
166 dev_err(&phydev->dev,
167 "Error: Read of BCM87XX_LASI_STATUS failed: %d\n", reg);
168 return 0;
169 }
170 return (reg & 1) != 0;
171}
172
173static int bcm87xx_ack_interrupt(struct phy_device *phydev)
174{
175 /* Reading the LASI status clears it. */
176 bcm87xx_did_interrupt(phydev);
177 return 0;
178}
179
180static int bcm8706_match_phy_device(struct phy_device *phydev)
181{
182 return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8706;
183}
184
185static int bcm8727_match_phy_device(struct phy_device *phydev)
186{
187 return phydev->c45_ids.device_ids[4] == PHY_ID_BCM8727;
188}
189
190static struct phy_driver bcm87xx_driver[] = {
191{
192 .phy_id = PHY_ID_BCM8706,
193 .phy_id_mask = 0xffffffff,
194 .name = "Broadcom BCM8706",
195 .flags = PHY_HAS_INTERRUPT,
196 .config_init = bcm87xx_config_init,
197 .config_aneg = bcm87xx_config_aneg,
198 .read_status = bcm87xx_read_status,
199 .ack_interrupt = bcm87xx_ack_interrupt,
200 .config_intr = bcm87xx_config_intr,
201 .did_interrupt = bcm87xx_did_interrupt,
202 .match_phy_device = bcm8706_match_phy_device,
203 .driver = { .owner = THIS_MODULE },
204}, {
205 .phy_id = PHY_ID_BCM8727,
206 .phy_id_mask = 0xffffffff,
207 .name = "Broadcom BCM8727",
208 .flags = PHY_HAS_INTERRUPT,
209 .config_init = bcm87xx_config_init,
210 .config_aneg = bcm87xx_config_aneg,
211 .read_status = bcm87xx_read_status,
212 .ack_interrupt = bcm87xx_ack_interrupt,
213 .config_intr = bcm87xx_config_intr,
214 .did_interrupt = bcm87xx_did_interrupt,
215 .match_phy_device = bcm8727_match_phy_device,
216 .driver = { .owner = THIS_MODULE },
217} };
218
219static int __init bcm87xx_init(void)
220{
221 return phy_drivers_register(bcm87xx_driver,
222 ARRAY_SIZE(bcm87xx_driver));
223}
224module_init(bcm87xx_init);
225
226static void __exit bcm87xx_exit(void)
227{
228 phy_drivers_unregister(bcm87xx_driver,
229 ARRAY_SIZE(bcm87xx_driver));
230}
231module_exit(bcm87xx_exit);
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 60338ff63092..f8c90ea75108 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -682,7 +682,8 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
682 return err; 682 return err;
683} 683}
684 684
685static struct phy_driver bcm5411_driver = { 685static struct phy_driver broadcom_drivers[] = {
686{
686 .phy_id = PHY_ID_BCM5411, 687 .phy_id = PHY_ID_BCM5411,
687 .phy_id_mask = 0xfffffff0, 688 .phy_id_mask = 0xfffffff0,
688 .name = "Broadcom BCM5411", 689 .name = "Broadcom BCM5411",
@@ -695,9 +696,7 @@ static struct phy_driver bcm5411_driver = {
695 .ack_interrupt = bcm54xx_ack_interrupt, 696 .ack_interrupt = bcm54xx_ack_interrupt,
696 .config_intr = bcm54xx_config_intr, 697 .config_intr = bcm54xx_config_intr,
697 .driver = { .owner = THIS_MODULE }, 698 .driver = { .owner = THIS_MODULE },
698}; 699}, {
699
700static struct phy_driver bcm5421_driver = {
701 .phy_id = PHY_ID_BCM5421, 700 .phy_id = PHY_ID_BCM5421,
702 .phy_id_mask = 0xfffffff0, 701 .phy_id_mask = 0xfffffff0,
703 .name = "Broadcom BCM5421", 702 .name = "Broadcom BCM5421",
@@ -710,9 +709,7 @@ static struct phy_driver bcm5421_driver = {
710 .ack_interrupt = bcm54xx_ack_interrupt, 709 .ack_interrupt = bcm54xx_ack_interrupt,
711 .config_intr = bcm54xx_config_intr, 710 .config_intr = bcm54xx_config_intr,
712 .driver = { .owner = THIS_MODULE }, 711 .driver = { .owner = THIS_MODULE },
713}; 712}, {
714
715static struct phy_driver bcm5461_driver = {
716 .phy_id = PHY_ID_BCM5461, 713 .phy_id = PHY_ID_BCM5461,
717 .phy_id_mask = 0xfffffff0, 714 .phy_id_mask = 0xfffffff0,
718 .name = "Broadcom BCM5461", 715 .name = "Broadcom BCM5461",
@@ -725,9 +722,7 @@ static struct phy_driver bcm5461_driver = {
725 .ack_interrupt = bcm54xx_ack_interrupt, 722 .ack_interrupt = bcm54xx_ack_interrupt,
726 .config_intr = bcm54xx_config_intr, 723 .config_intr = bcm54xx_config_intr,
727 .driver = { .owner = THIS_MODULE }, 724 .driver = { .owner = THIS_MODULE },
728}; 725}, {
729
730static struct phy_driver bcm5464_driver = {
731 .phy_id = PHY_ID_BCM5464, 726 .phy_id = PHY_ID_BCM5464,
732 .phy_id_mask = 0xfffffff0, 727 .phy_id_mask = 0xfffffff0,
733 .name = "Broadcom BCM5464", 728 .name = "Broadcom BCM5464",
@@ -740,9 +735,7 @@ static struct phy_driver bcm5464_driver = {
740 .ack_interrupt = bcm54xx_ack_interrupt, 735 .ack_interrupt = bcm54xx_ack_interrupt,
741 .config_intr = bcm54xx_config_intr, 736 .config_intr = bcm54xx_config_intr,
742 .driver = { .owner = THIS_MODULE }, 737 .driver = { .owner = THIS_MODULE },
743}; 738}, {
744
745static struct phy_driver bcm5481_driver = {
746 .phy_id = PHY_ID_BCM5481, 739 .phy_id = PHY_ID_BCM5481,
747 .phy_id_mask = 0xfffffff0, 740 .phy_id_mask = 0xfffffff0,
748 .name = "Broadcom BCM5481", 741 .name = "Broadcom BCM5481",
@@ -755,9 +748,7 @@ static struct phy_driver bcm5481_driver = {
755 .ack_interrupt = bcm54xx_ack_interrupt, 748 .ack_interrupt = bcm54xx_ack_interrupt,
756 .config_intr = bcm54xx_config_intr, 749 .config_intr = bcm54xx_config_intr,
757 .driver = { .owner = THIS_MODULE }, 750 .driver = { .owner = THIS_MODULE },
758}; 751}, {
759
760static struct phy_driver bcm5482_driver = {
761 .phy_id = PHY_ID_BCM5482, 752 .phy_id = PHY_ID_BCM5482,
762 .phy_id_mask = 0xfffffff0, 753 .phy_id_mask = 0xfffffff0,
763 .name = "Broadcom BCM5482", 754 .name = "Broadcom BCM5482",
@@ -770,9 +761,7 @@ static struct phy_driver bcm5482_driver = {
770 .ack_interrupt = bcm54xx_ack_interrupt, 761 .ack_interrupt = bcm54xx_ack_interrupt,
771 .config_intr = bcm54xx_config_intr, 762 .config_intr = bcm54xx_config_intr,
772 .driver = { .owner = THIS_MODULE }, 763 .driver = { .owner = THIS_MODULE },
773}; 764}, {
774
775static struct phy_driver bcm50610_driver = {
776 .phy_id = PHY_ID_BCM50610, 765 .phy_id = PHY_ID_BCM50610,
777 .phy_id_mask = 0xfffffff0, 766 .phy_id_mask = 0xfffffff0,
778 .name = "Broadcom BCM50610", 767 .name = "Broadcom BCM50610",
@@ -785,9 +774,7 @@ static struct phy_driver bcm50610_driver = {
785 .ack_interrupt = bcm54xx_ack_interrupt, 774 .ack_interrupt = bcm54xx_ack_interrupt,
786 .config_intr = bcm54xx_config_intr, 775 .config_intr = bcm54xx_config_intr,
787 .driver = { .owner = THIS_MODULE }, 776 .driver = { .owner = THIS_MODULE },
788}; 777}, {
789
790static struct phy_driver bcm50610m_driver = {
791 .phy_id = PHY_ID_BCM50610M, 778 .phy_id = PHY_ID_BCM50610M,
792 .phy_id_mask = 0xfffffff0, 779 .phy_id_mask = 0xfffffff0,
793 .name = "Broadcom BCM50610M", 780 .name = "Broadcom BCM50610M",
@@ -800,9 +787,7 @@ static struct phy_driver bcm50610m_driver = {
800 .ack_interrupt = bcm54xx_ack_interrupt, 787 .ack_interrupt = bcm54xx_ack_interrupt,
801 .config_intr = bcm54xx_config_intr, 788 .config_intr = bcm54xx_config_intr,
802 .driver = { .owner = THIS_MODULE }, 789 .driver = { .owner = THIS_MODULE },
803}; 790}, {
804
805static struct phy_driver bcm57780_driver = {
806 .phy_id = PHY_ID_BCM57780, 791 .phy_id = PHY_ID_BCM57780,
807 .phy_id_mask = 0xfffffff0, 792 .phy_id_mask = 0xfffffff0,
808 .name = "Broadcom BCM57780", 793 .name = "Broadcom BCM57780",
@@ -815,9 +800,7 @@ static struct phy_driver bcm57780_driver = {
815 .ack_interrupt = bcm54xx_ack_interrupt, 800 .ack_interrupt = bcm54xx_ack_interrupt,
816 .config_intr = bcm54xx_config_intr, 801 .config_intr = bcm54xx_config_intr,
817 .driver = { .owner = THIS_MODULE }, 802 .driver = { .owner = THIS_MODULE },
818}; 803}, {
819
820static struct phy_driver bcmac131_driver = {
821 .phy_id = PHY_ID_BCMAC131, 804 .phy_id = PHY_ID_BCMAC131,
822 .phy_id_mask = 0xfffffff0, 805 .phy_id_mask = 0xfffffff0,
823 .name = "Broadcom BCMAC131", 806 .name = "Broadcom BCMAC131",
@@ -830,9 +813,7 @@ static struct phy_driver bcmac131_driver = {
830 .ack_interrupt = brcm_fet_ack_interrupt, 813 .ack_interrupt = brcm_fet_ack_interrupt,
831 .config_intr = brcm_fet_config_intr, 814 .config_intr = brcm_fet_config_intr,
832 .driver = { .owner = THIS_MODULE }, 815 .driver = { .owner = THIS_MODULE },
833}; 816}, {
834
835static struct phy_driver bcm5241_driver = {
836 .phy_id = PHY_ID_BCM5241, 817 .phy_id = PHY_ID_BCM5241,
837 .phy_id_mask = 0xfffffff0, 818 .phy_id_mask = 0xfffffff0,
838 .name = "Broadcom BCM5241", 819 .name = "Broadcom BCM5241",
@@ -845,84 +826,18 @@ static struct phy_driver bcm5241_driver = {
845 .ack_interrupt = brcm_fet_ack_interrupt, 826 .ack_interrupt = brcm_fet_ack_interrupt,
846 .config_intr = brcm_fet_config_intr, 827 .config_intr = brcm_fet_config_intr,
847 .driver = { .owner = THIS_MODULE }, 828 .driver = { .owner = THIS_MODULE },
848}; 829} };
849 830
850static int __init broadcom_init(void) 831static int __init broadcom_init(void)
851{ 832{
852 int ret; 833 return phy_drivers_register(broadcom_drivers,
853 834 ARRAY_SIZE(broadcom_drivers));
854 ret = phy_driver_register(&bcm5411_driver);
855 if (ret)
856 goto out_5411;
857 ret = phy_driver_register(&bcm5421_driver);
858 if (ret)
859 goto out_5421;
860 ret = phy_driver_register(&bcm5461_driver);
861 if (ret)
862 goto out_5461;
863 ret = phy_driver_register(&bcm5464_driver);
864 if (ret)
865 goto out_5464;
866 ret = phy_driver_register(&bcm5481_driver);
867 if (ret)
868 goto out_5481;
869 ret = phy_driver_register(&bcm5482_driver);
870 if (ret)
871 goto out_5482;
872 ret = phy_driver_register(&bcm50610_driver);
873 if (ret)
874 goto out_50610;
875 ret = phy_driver_register(&bcm50610m_driver);
876 if (ret)
877 goto out_50610m;
878 ret = phy_driver_register(&bcm57780_driver);
879 if (ret)
880 goto out_57780;
881 ret = phy_driver_register(&bcmac131_driver);
882 if (ret)
883 goto out_ac131;
884 ret = phy_driver_register(&bcm5241_driver);
885 if (ret)
886 goto out_5241;
887 return ret;
888
889out_5241:
890 phy_driver_unregister(&bcmac131_driver);
891out_ac131:
892 phy_driver_unregister(&bcm57780_driver);
893out_57780:
894 phy_driver_unregister(&bcm50610m_driver);
895out_50610m:
896 phy_driver_unregister(&bcm50610_driver);
897out_50610:
898 phy_driver_unregister(&bcm5482_driver);
899out_5482:
900 phy_driver_unregister(&bcm5481_driver);
901out_5481:
902 phy_driver_unregister(&bcm5464_driver);
903out_5464:
904 phy_driver_unregister(&bcm5461_driver);
905out_5461:
906 phy_driver_unregister(&bcm5421_driver);
907out_5421:
908 phy_driver_unregister(&bcm5411_driver);
909out_5411:
910 return ret;
911} 835}
912 836
913static void __exit broadcom_exit(void) 837static void __exit broadcom_exit(void)
914{ 838{
915 phy_driver_unregister(&bcm5241_driver); 839 phy_drivers_unregister(broadcom_drivers,
916 phy_driver_unregister(&bcmac131_driver); 840 ARRAY_SIZE(broadcom_drivers));
917 phy_driver_unregister(&bcm57780_driver);
918 phy_driver_unregister(&bcm50610m_driver);
919 phy_driver_unregister(&bcm50610_driver);
920 phy_driver_unregister(&bcm5482_driver);
921 phy_driver_unregister(&bcm5481_driver);
922 phy_driver_unregister(&bcm5464_driver);
923 phy_driver_unregister(&bcm5461_driver);
924 phy_driver_unregister(&bcm5421_driver);
925 phy_driver_unregister(&bcm5411_driver);
926} 841}
927 842
928module_init(broadcom_init); 843module_init(broadcom_init);
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
index d28173161c21..db472ffb6e89 100644
--- a/drivers/net/phy/cicada.c
+++ b/drivers/net/phy/cicada.c
@@ -102,7 +102,8 @@ static int cis820x_config_intr(struct phy_device *phydev)
102} 102}
103 103
104/* Cicada 8201, a.k.a Vitesse VSC8201 */ 104/* Cicada 8201, a.k.a Vitesse VSC8201 */
105static struct phy_driver cis8201_driver = { 105static struct phy_driver cis820x_driver[] = {
106{
106 .phy_id = 0x000fc410, 107 .phy_id = 0x000fc410,
107 .name = "Cicada Cis8201", 108 .name = "Cicada Cis8201",
108 .phy_id_mask = 0x000ffff0, 109 .phy_id_mask = 0x000ffff0,
@@ -113,11 +114,8 @@ static struct phy_driver cis8201_driver = {
113 .read_status = &genphy_read_status, 114 .read_status = &genphy_read_status,
114 .ack_interrupt = &cis820x_ack_interrupt, 115 .ack_interrupt = &cis820x_ack_interrupt,
115 .config_intr = &cis820x_config_intr, 116 .config_intr = &cis820x_config_intr,
116 .driver = { .owner = THIS_MODULE,}, 117 .driver = { .owner = THIS_MODULE,},
117}; 118}, {
118
119/* Cicada 8204 */
120static struct phy_driver cis8204_driver = {
121 .phy_id = 0x000fc440, 119 .phy_id = 0x000fc440,
122 .name = "Cicada Cis8204", 120 .name = "Cicada Cis8204",
123 .phy_id_mask = 0x000fffc0, 121 .phy_id_mask = 0x000fffc0,
@@ -128,32 +126,19 @@ static struct phy_driver cis8204_driver = {
128 .read_status = &genphy_read_status, 126 .read_status = &genphy_read_status,
129 .ack_interrupt = &cis820x_ack_interrupt, 127 .ack_interrupt = &cis820x_ack_interrupt,
130 .config_intr = &cis820x_config_intr, 128 .config_intr = &cis820x_config_intr,
131 .driver = { .owner = THIS_MODULE,}, 129 .driver = { .owner = THIS_MODULE,},
132}; 130} };
133 131
134static int __init cicada_init(void) 132static int __init cicada_init(void)
135{ 133{
136 int ret; 134 return phy_drivers_register(cis820x_driver,
137 135 ARRAY_SIZE(cis820x_driver));
138 ret = phy_driver_register(&cis8204_driver);
139 if (ret)
140 goto err1;
141
142 ret = phy_driver_register(&cis8201_driver);
143 if (ret)
144 goto err2;
145 return 0;
146
147err2:
148 phy_driver_unregister(&cis8204_driver);
149err1:
150 return ret;
151} 136}
152 137
153static void __exit cicada_exit(void) 138static void __exit cicada_exit(void)
154{ 139{
155 phy_driver_unregister(&cis8204_driver); 140 phy_drivers_unregister(cis820x_driver,
156 phy_driver_unregister(&cis8201_driver); 141 ARRAY_SIZE(cis820x_driver));
157} 142}
158 143
159module_init(cicada_init); 144module_init(cicada_init);
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 5f59cc064778..81c7bc010dd8 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -144,7 +144,8 @@ static int dm9161_ack_interrupt(struct phy_device *phydev)
144 return (err < 0) ? err : 0; 144 return (err < 0) ? err : 0;
145} 145}
146 146
147static struct phy_driver dm9161e_driver = { 147static struct phy_driver dm91xx_driver[] = {
148{
148 .phy_id = 0x0181b880, 149 .phy_id = 0x0181b880,
149 .name = "Davicom DM9161E", 150 .name = "Davicom DM9161E",
150 .phy_id_mask = 0x0ffffff0, 151 .phy_id_mask = 0x0ffffff0,
@@ -153,9 +154,7 @@ static struct phy_driver dm9161e_driver = {
153 .config_aneg = dm9161_config_aneg, 154 .config_aneg = dm9161_config_aneg,
154 .read_status = genphy_read_status, 155 .read_status = genphy_read_status,
155 .driver = { .owner = THIS_MODULE,}, 156 .driver = { .owner = THIS_MODULE,},
156}; 157}, {
157
158static struct phy_driver dm9161a_driver = {
159 .phy_id = 0x0181b8a0, 158 .phy_id = 0x0181b8a0,
160 .name = "Davicom DM9161A", 159 .name = "Davicom DM9161A",
161 .phy_id_mask = 0x0ffffff0, 160 .phy_id_mask = 0x0ffffff0,
@@ -164,9 +163,7 @@ static struct phy_driver dm9161a_driver = {
164 .config_aneg = dm9161_config_aneg, 163 .config_aneg = dm9161_config_aneg,
165 .read_status = genphy_read_status, 164 .read_status = genphy_read_status,
166 .driver = { .owner = THIS_MODULE,}, 165 .driver = { .owner = THIS_MODULE,},
167}; 166}, {
168
169static struct phy_driver dm9131_driver = {
170 .phy_id = 0x00181b80, 167 .phy_id = 0x00181b80,
171 .name = "Davicom DM9131", 168 .name = "Davicom DM9131",
172 .phy_id_mask = 0x0ffffff0, 169 .phy_id_mask = 0x0ffffff0,
@@ -177,38 +174,18 @@ static struct phy_driver dm9131_driver = {
177 .ack_interrupt = dm9161_ack_interrupt, 174 .ack_interrupt = dm9161_ack_interrupt,
178 .config_intr = dm9161_config_intr, 175 .config_intr = dm9161_config_intr,
179 .driver = { .owner = THIS_MODULE,}, 176 .driver = { .owner = THIS_MODULE,},
180}; 177} };
181 178
182static int __init davicom_init(void) 179static int __init davicom_init(void)
183{ 180{
184 int ret; 181 return phy_drivers_register(dm91xx_driver,
185 182 ARRAY_SIZE(dm91xx_driver));
186 ret = phy_driver_register(&dm9161e_driver);
187 if (ret)
188 goto err1;
189
190 ret = phy_driver_register(&dm9161a_driver);
191 if (ret)
192 goto err2;
193
194 ret = phy_driver_register(&dm9131_driver);
195 if (ret)
196 goto err3;
197 return 0;
198
199 err3:
200 phy_driver_unregister(&dm9161a_driver);
201 err2:
202 phy_driver_unregister(&dm9161e_driver);
203 err1:
204 return ret;
205} 183}
206 184
207static void __exit davicom_exit(void) 185static void __exit davicom_exit(void)
208{ 186{
209 phy_driver_unregister(&dm9161e_driver); 187 phy_drivers_unregister(dm91xx_driver,
210 phy_driver_unregister(&dm9161a_driver); 188 ARRAY_SIZE(dm91xx_driver));
211 phy_driver_unregister(&dm9131_driver);
212} 189}
213 190
214module_init(davicom_init); 191module_init(davicom_init);
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 940b29022d0c..b0da0226661f 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -17,6 +17,9 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */ 19 */
20
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
20#include <linux/ethtool.h> 23#include <linux/ethtool.h>
21#include <linux/kernel.h> 24#include <linux/kernel.h>
22#include <linux/list.h> 25#include <linux/list.h>
@@ -453,16 +456,16 @@ static void enable_status_frames(struct phy_device *phydev, bool on)
453 ext_write(0, phydev, PAGE6, PSF_CFG1, ver); 456 ext_write(0, phydev, PAGE6, PSF_CFG1, ver);
454 457
455 if (!phydev->attached_dev) { 458 if (!phydev->attached_dev) {
456 pr_warning("dp83640: expected to find an attached netdevice\n"); 459 pr_warn("expected to find an attached netdevice\n");
457 return; 460 return;
458 } 461 }
459 462
460 if (on) { 463 if (on) {
461 if (dev_mc_add(phydev->attached_dev, status_frame_dst)) 464 if (dev_mc_add(phydev->attached_dev, status_frame_dst))
462 pr_warning("dp83640: failed to add mc address\n"); 465 pr_warn("failed to add mc address\n");
463 } else { 466 } else {
464 if (dev_mc_del(phydev->attached_dev, status_frame_dst)) 467 if (dev_mc_del(phydev->attached_dev, status_frame_dst))
465 pr_warning("dp83640: failed to delete mc address\n"); 468 pr_warn("failed to delete mc address\n");
466 } 469 }
467} 470}
468 471
@@ -582,9 +585,9 @@ static void recalibrate(struct dp83640_clock *clock)
582 * read out and correct offsets 585 * read out and correct offsets
583 */ 586 */
584 val = ext_read(master, PAGE4, PTP_STS); 587 val = ext_read(master, PAGE4, PTP_STS);
585 pr_info("master PTP_STS 0x%04hx", val); 588 pr_info("master PTP_STS 0x%04hx\n", val);
586 val = ext_read(master, PAGE4, PTP_ESTS); 589 val = ext_read(master, PAGE4, PTP_ESTS);
587 pr_info("master PTP_ESTS 0x%04hx", val); 590 pr_info("master PTP_ESTS 0x%04hx\n", val);
588 event_ts.ns_lo = ext_read(master, PAGE4, PTP_EDATA); 591 event_ts.ns_lo = ext_read(master, PAGE4, PTP_EDATA);
589 event_ts.ns_hi = ext_read(master, PAGE4, PTP_EDATA); 592 event_ts.ns_hi = ext_read(master, PAGE4, PTP_EDATA);
590 event_ts.sec_lo = ext_read(master, PAGE4, PTP_EDATA); 593 event_ts.sec_lo = ext_read(master, PAGE4, PTP_EDATA);
@@ -594,9 +597,9 @@ static void recalibrate(struct dp83640_clock *clock)
594 list_for_each(this, &clock->phylist) { 597 list_for_each(this, &clock->phylist) {
595 tmp = list_entry(this, struct dp83640_private, list); 598 tmp = list_entry(this, struct dp83640_private, list);
596 val = ext_read(tmp->phydev, PAGE4, PTP_STS); 599 val = ext_read(tmp->phydev, PAGE4, PTP_STS);
597 pr_info("slave PTP_STS 0x%04hx", val); 600 pr_info("slave PTP_STS 0x%04hx\n", val);
598 val = ext_read(tmp->phydev, PAGE4, PTP_ESTS); 601 val = ext_read(tmp->phydev, PAGE4, PTP_ESTS);
599 pr_info("slave PTP_ESTS 0x%04hx", val); 602 pr_info("slave PTP_ESTS 0x%04hx\n", val);
600 event_ts.ns_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); 603 event_ts.ns_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA);
601 event_ts.ns_hi = ext_read(tmp->phydev, PAGE4, PTP_EDATA); 604 event_ts.ns_hi = ext_read(tmp->phydev, PAGE4, PTP_EDATA);
602 event_ts.sec_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); 605 event_ts.sec_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA);
@@ -686,7 +689,7 @@ static void decode_rxts(struct dp83640_private *dp83640,
686 prune_rx_ts(dp83640); 689 prune_rx_ts(dp83640);
687 690
688 if (list_empty(&dp83640->rxpool)) { 691 if (list_empty(&dp83640->rxpool)) {
689 pr_debug("dp83640: rx timestamp pool is empty\n"); 692 pr_debug("rx timestamp pool is empty\n");
690 goto out; 693 goto out;
691 } 694 }
692 rxts = list_first_entry(&dp83640->rxpool, struct rxts, list); 695 rxts = list_first_entry(&dp83640->rxpool, struct rxts, list);
@@ -709,7 +712,7 @@ static void decode_txts(struct dp83640_private *dp83640,
709 skb = skb_dequeue(&dp83640->tx_queue); 712 skb = skb_dequeue(&dp83640->tx_queue);
710 713
711 if (!skb) { 714 if (!skb) {
712 pr_debug("dp83640: have timestamp but tx_queue empty\n"); 715 pr_debug("have timestamp but tx_queue empty\n");
713 return; 716 return;
714 } 717 }
715 ns = phy2txts(phy_txts); 718 ns = phy2txts(phy_txts);
@@ -847,7 +850,7 @@ static void dp83640_free_clocks(void)
847 list_for_each_safe(this, next, &phyter_clocks) { 850 list_for_each_safe(this, next, &phyter_clocks) {
848 clock = list_entry(this, struct dp83640_clock, list); 851 clock = list_entry(this, struct dp83640_clock, list);
849 if (!list_empty(&clock->phylist)) { 852 if (!list_empty(&clock->phylist)) {
850 pr_warning("phy list non-empty while unloading"); 853 pr_warn("phy list non-empty while unloading\n");
851 BUG(); 854 BUG();
852 } 855 }
853 list_del(&clock->list); 856 list_del(&clock->list);
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 633680d0828e..ba55adfc7aae 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -70,7 +70,7 @@ static int fixed_phy_update_regs(struct fixed_phy *fp)
70 lpa |= LPA_10FULL; 70 lpa |= LPA_10FULL;
71 break; 71 break;
72 default: 72 default:
73 printk(KERN_WARNING "fixed phy: unknown speed\n"); 73 pr_warn("fixed phy: unknown speed\n");
74 return -EINVAL; 74 return -EINVAL;
75 } 75 }
76 } else { 76 } else {
@@ -90,7 +90,7 @@ static int fixed_phy_update_regs(struct fixed_phy *fp)
90 lpa |= LPA_10HALF; 90 lpa |= LPA_10HALF;
91 break; 91 break;
92 default: 92 default:
93 printk(KERN_WARNING "fixed phy: unknown speed\n"); 93 pr_warn("fixed phy: unknown speed\n");
94 return -EINVAL; 94 return -EINVAL;
95 } 95 }
96 } 96 }
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 47f8e8939266..d5199cb4caec 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -202,7 +202,8 @@ static int ip101a_g_ack_interrupt(struct phy_device *phydev)
202 return 0; 202 return 0;
203} 203}
204 204
205static struct phy_driver ip175c_driver = { 205static struct phy_driver icplus_driver[] = {
206{
206 .phy_id = 0x02430d80, 207 .phy_id = 0x02430d80,
207 .name = "ICPlus IP175C", 208 .name = "ICPlus IP175C",
208 .phy_id_mask = 0x0ffffff0, 209 .phy_id_mask = 0x0ffffff0,
@@ -213,9 +214,7 @@ static struct phy_driver ip175c_driver = {
213 .suspend = genphy_suspend, 214 .suspend = genphy_suspend,
214 .resume = genphy_resume, 215 .resume = genphy_resume,
215 .driver = { .owner = THIS_MODULE,}, 216 .driver = { .owner = THIS_MODULE,},
216}; 217}, {
217
218static struct phy_driver ip1001_driver = {
219 .phy_id = 0x02430d90, 218 .phy_id = 0x02430d90,
220 .name = "ICPlus IP1001", 219 .name = "ICPlus IP1001",
221 .phy_id_mask = 0x0ffffff0, 220 .phy_id_mask = 0x0ffffff0,
@@ -227,9 +226,7 @@ static struct phy_driver ip1001_driver = {
227 .suspend = genphy_suspend, 226 .suspend = genphy_suspend,
228 .resume = genphy_resume, 227 .resume = genphy_resume,
229 .driver = { .owner = THIS_MODULE,}, 228 .driver = { .owner = THIS_MODULE,},
230}; 229}, {
231
232static struct phy_driver ip101a_g_driver = {
233 .phy_id = 0x02430c54, 230 .phy_id = 0x02430c54,
234 .name = "ICPlus IP101A/G", 231 .name = "ICPlus IP101A/G",
235 .phy_id_mask = 0x0ffffff0, 232 .phy_id_mask = 0x0ffffff0,
@@ -243,28 +240,18 @@ static struct phy_driver ip101a_g_driver = {
243 .suspend = genphy_suspend, 240 .suspend = genphy_suspend,
244 .resume = genphy_resume, 241 .resume = genphy_resume,
245 .driver = { .owner = THIS_MODULE,}, 242 .driver = { .owner = THIS_MODULE,},
246}; 243} };
247 244
248static int __init icplus_init(void) 245static int __init icplus_init(void)
249{ 246{
250 int ret = 0; 247 return phy_drivers_register(icplus_driver,
251 248 ARRAY_SIZE(icplus_driver));
252 ret = phy_driver_register(&ip1001_driver);
253 if (ret < 0)
254 return -ENODEV;
255
256 ret = phy_driver_register(&ip101a_g_driver);
257 if (ret < 0)
258 return -ENODEV;
259
260 return phy_driver_register(&ip175c_driver);
261} 249}
262 250
263static void __exit icplus_exit(void) 251static void __exit icplus_exit(void)
264{ 252{
265 phy_driver_unregister(&ip1001_driver); 253 phy_drivers_unregister(icplus_driver,
266 phy_driver_unregister(&ip101a_g_driver); 254 ARRAY_SIZE(icplus_driver));
267 phy_driver_unregister(&ip175c_driver);
268} 255}
269 256
270module_init(icplus_init); 257module_init(icplus_init);
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index 6f6e8b616a62..6d1e3fcc43e2 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -149,7 +149,8 @@ static int lxt973_config_aneg(struct phy_device *phydev)
149 return phydev->priv ? 0 : genphy_config_aneg(phydev); 149 return phydev->priv ? 0 : genphy_config_aneg(phydev);
150} 150}
151 151
152static struct phy_driver lxt970_driver = { 152static struct phy_driver lxt97x_driver[] = {
153{
153 .phy_id = 0x78100000, 154 .phy_id = 0x78100000,
154 .name = "LXT970", 155 .name = "LXT970",
155 .phy_id_mask = 0xfffffff0, 156 .phy_id_mask = 0xfffffff0,
@@ -160,10 +161,8 @@ static struct phy_driver lxt970_driver = {
160 .read_status = genphy_read_status, 161 .read_status = genphy_read_status,
161 .ack_interrupt = lxt970_ack_interrupt, 162 .ack_interrupt = lxt970_ack_interrupt,
162 .config_intr = lxt970_config_intr, 163 .config_intr = lxt970_config_intr,
163 .driver = { .owner = THIS_MODULE,}, 164 .driver = { .owner = THIS_MODULE,},
164}; 165}, {
165
166static struct phy_driver lxt971_driver = {
167 .phy_id = 0x001378e0, 166 .phy_id = 0x001378e0,
168 .name = "LXT971", 167 .name = "LXT971",
169 .phy_id_mask = 0xfffffff0, 168 .phy_id_mask = 0xfffffff0,
@@ -173,10 +172,8 @@ static struct phy_driver lxt971_driver = {
173 .read_status = genphy_read_status, 172 .read_status = genphy_read_status,
174 .ack_interrupt = lxt971_ack_interrupt, 173 .ack_interrupt = lxt971_ack_interrupt,
175 .config_intr = lxt971_config_intr, 174 .config_intr = lxt971_config_intr,
176 .driver = { .owner = THIS_MODULE,}, 175 .driver = { .owner = THIS_MODULE,},
177}; 176}, {
178
179static struct phy_driver lxt973_driver = {
180 .phy_id = 0x00137a10, 177 .phy_id = 0x00137a10,
181 .name = "LXT973", 178 .name = "LXT973",
182 .phy_id_mask = 0xfffffff0, 179 .phy_id_mask = 0xfffffff0,
@@ -185,39 +182,19 @@ static struct phy_driver lxt973_driver = {
185 .probe = lxt973_probe, 182 .probe = lxt973_probe,
186 .config_aneg = lxt973_config_aneg, 183 .config_aneg = lxt973_config_aneg,
187 .read_status = genphy_read_status, 184 .read_status = genphy_read_status,
188 .driver = { .owner = THIS_MODULE,}, 185 .driver = { .owner = THIS_MODULE,},
189}; 186} };
190 187
191static int __init lxt_init(void) 188static int __init lxt_init(void)
192{ 189{
193 int ret; 190 return phy_drivers_register(lxt97x_driver,
194 191 ARRAY_SIZE(lxt97x_driver));
195 ret = phy_driver_register(&lxt970_driver);
196 if (ret)
197 goto err1;
198
199 ret = phy_driver_register(&lxt971_driver);
200 if (ret)
201 goto err2;
202
203 ret = phy_driver_register(&lxt973_driver);
204 if (ret)
205 goto err3;
206 return 0;
207
208 err3:
209 phy_driver_unregister(&lxt971_driver);
210 err2:
211 phy_driver_unregister(&lxt970_driver);
212 err1:
213 return ret;
214} 192}
215 193
216static void __exit lxt_exit(void) 194static void __exit lxt_exit(void)
217{ 195{
218 phy_driver_unregister(&lxt970_driver); 196 phy_drivers_unregister(lxt97x_driver,
219 phy_driver_unregister(&lxt971_driver); 197 ARRAY_SIZE(lxt97x_driver));
220 phy_driver_unregister(&lxt973_driver);
221} 198}
222 199
223module_init(lxt_init); 200module_init(lxt_init);
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 418928d644bf..5d2a3f215887 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -826,28 +826,14 @@ static struct phy_driver marvell_drivers[] = {
826 826
827static int __init marvell_init(void) 827static int __init marvell_init(void)
828{ 828{
829 int ret; 829 return phy_drivers_register(marvell_drivers,
830 int i; 830 ARRAY_SIZE(marvell_drivers));
831
832 for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) {
833 ret = phy_driver_register(&marvell_drivers[i]);
834
835 if (ret) {
836 while (i-- > 0)
837 phy_driver_unregister(&marvell_drivers[i]);
838 return ret;
839 }
840 }
841
842 return 0;
843} 831}
844 832
845static void __exit marvell_exit(void) 833static void __exit marvell_exit(void)
846{ 834{
847 int i; 835 phy_drivers_unregister(marvell_drivers,
848 836 ARRAY_SIZE(marvell_drivers));
849 for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++)
850 phy_driver_unregister(&marvell_drivers[i]);
851} 837}
852 838
853module_init(marvell_init); 839module_init(marvell_init);
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 5061608f408c..170eb411ab5d 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -13,6 +13,9 @@
13 * option) any later version. 13 * option) any later version.
14 * 14 *
15 */ 15 */
16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
16#include <linux/kernel.h> 19#include <linux/kernel.h>
17#include <linux/string.h> 20#include <linux/string.h>
18#include <linux/errno.h> 21#include <linux/errno.h>
@@ -22,6 +25,7 @@
22#include <linux/init.h> 25#include <linux/init.h>
23#include <linux/delay.h> 26#include <linux/delay.h>
24#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/of_device.h>
25#include <linux/netdevice.h> 29#include <linux/netdevice.h>
26#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
27#include <linux/skbuff.h> 31#include <linux/skbuff.h>
@@ -148,7 +152,7 @@ int mdiobus_register(struct mii_bus *bus)
148 152
149 err = device_register(&bus->dev); 153 err = device_register(&bus->dev);
150 if (err) { 154 if (err) {
151 printk(KERN_ERR "mii_bus %s failed to register\n", bus->id); 155 pr_err("mii_bus %s failed to register\n", bus->id);
152 return -EINVAL; 156 return -EINVAL;
153 } 157 }
154 158
@@ -229,7 +233,7 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
229 struct phy_device *phydev; 233 struct phy_device *phydev;
230 int err; 234 int err;
231 235
232 phydev = get_phy_device(bus, addr); 236 phydev = get_phy_device(bus, addr, false);
233 if (IS_ERR(phydev) || phydev == NULL) 237 if (IS_ERR(phydev) || phydev == NULL)
234 return phydev; 238 return phydev;
235 239
@@ -305,6 +309,12 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv)
305 struct phy_device *phydev = to_phy_device(dev); 309 struct phy_device *phydev = to_phy_device(dev);
306 struct phy_driver *phydrv = to_phy_driver(drv); 310 struct phy_driver *phydrv = to_phy_driver(drv);
307 311
312 if (of_driver_match_device(dev, drv))
313 return 1;
314
315 if (phydrv->match_phy_device)
316 return phydrv->match_phy_device(phydev);
317
308 return ((phydrv->phy_id & phydrv->phy_id_mask) == 318 return ((phydrv->phy_id & phydrv->phy_id_mask) ==
309 (phydev->phy_id & phydrv->phy_id_mask)); 319 (phydev->phy_id & phydrv->phy_id_mask));
310} 320}
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 9d6c80c8a0cf..cf287e0eb408 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -114,7 +114,8 @@ static int ks8051_config_init(struct phy_device *phydev)
114 return 0; 114 return 0;
115} 115}
116 116
117static struct phy_driver ks8737_driver = { 117static struct phy_driver ksphy_driver[] = {
118{
118 .phy_id = PHY_ID_KS8737, 119 .phy_id = PHY_ID_KS8737,
119 .phy_id_mask = 0x00fffff0, 120 .phy_id_mask = 0x00fffff0,
120 .name = "Micrel KS8737", 121 .name = "Micrel KS8737",
@@ -126,9 +127,7 @@ static struct phy_driver ks8737_driver = {
126 .ack_interrupt = kszphy_ack_interrupt, 127 .ack_interrupt = kszphy_ack_interrupt,
127 .config_intr = ks8737_config_intr, 128 .config_intr = ks8737_config_intr,
128 .driver = { .owner = THIS_MODULE,}, 129 .driver = { .owner = THIS_MODULE,},
129}; 130}, {
130
131static struct phy_driver ks8041_driver = {
132 .phy_id = PHY_ID_KS8041, 131 .phy_id = PHY_ID_KS8041,
133 .phy_id_mask = 0x00fffff0, 132 .phy_id_mask = 0x00fffff0,
134 .name = "Micrel KS8041", 133 .name = "Micrel KS8041",
@@ -141,9 +140,7 @@ static struct phy_driver ks8041_driver = {
141 .ack_interrupt = kszphy_ack_interrupt, 140 .ack_interrupt = kszphy_ack_interrupt,
142 .config_intr = kszphy_config_intr, 141 .config_intr = kszphy_config_intr,
143 .driver = { .owner = THIS_MODULE,}, 142 .driver = { .owner = THIS_MODULE,},
144}; 143}, {
145
146static struct phy_driver ks8051_driver = {
147 .phy_id = PHY_ID_KS8051, 144 .phy_id = PHY_ID_KS8051,
148 .phy_id_mask = 0x00fffff0, 145 .phy_id_mask = 0x00fffff0,
149 .name = "Micrel KS8051", 146 .name = "Micrel KS8051",
@@ -156,9 +153,7 @@ static struct phy_driver ks8051_driver = {
156 .ack_interrupt = kszphy_ack_interrupt, 153 .ack_interrupt = kszphy_ack_interrupt,
157 .config_intr = kszphy_config_intr, 154 .config_intr = kszphy_config_intr,
158 .driver = { .owner = THIS_MODULE,}, 155 .driver = { .owner = THIS_MODULE,},
159}; 156}, {
160
161static struct phy_driver ks8001_driver = {
162 .phy_id = PHY_ID_KS8001, 157 .phy_id = PHY_ID_KS8001,
163 .name = "Micrel KS8001 or KS8721", 158 .name = "Micrel KS8001 or KS8721",
164 .phy_id_mask = 0x00ffffff, 159 .phy_id_mask = 0x00ffffff,
@@ -170,9 +165,7 @@ static struct phy_driver ks8001_driver = {
170 .ack_interrupt = kszphy_ack_interrupt, 165 .ack_interrupt = kszphy_ack_interrupt,
171 .config_intr = kszphy_config_intr, 166 .config_intr = kszphy_config_intr,
172 .driver = { .owner = THIS_MODULE,}, 167 .driver = { .owner = THIS_MODULE,},
173}; 168}, {
174
175static struct phy_driver ksz9021_driver = {
176 .phy_id = PHY_ID_KSZ9021, 169 .phy_id = PHY_ID_KSZ9021,
177 .phy_id_mask = 0x000ffffe, 170 .phy_id_mask = 0x000ffffe,
178 .name = "Micrel KSZ9021 Gigabit PHY", 171 .name = "Micrel KSZ9021 Gigabit PHY",
@@ -185,51 +178,18 @@ static struct phy_driver ksz9021_driver = {
185 .ack_interrupt = kszphy_ack_interrupt, 178 .ack_interrupt = kszphy_ack_interrupt,
186 .config_intr = ksz9021_config_intr, 179 .config_intr = ksz9021_config_intr,
187 .driver = { .owner = THIS_MODULE, }, 180 .driver = { .owner = THIS_MODULE, },
188}; 181} };
189 182
190static int __init ksphy_init(void) 183static int __init ksphy_init(void)
191{ 184{
192 int ret; 185 return phy_drivers_register(ksphy_driver,
193 186 ARRAY_SIZE(ksphy_driver));
194 ret = phy_driver_register(&ks8001_driver);
195 if (ret)
196 goto err1;
197
198 ret = phy_driver_register(&ksz9021_driver);
199 if (ret)
200 goto err2;
201
202 ret = phy_driver_register(&ks8737_driver);
203 if (ret)
204 goto err3;
205 ret = phy_driver_register(&ks8041_driver);
206 if (ret)
207 goto err4;
208 ret = phy_driver_register(&ks8051_driver);
209 if (ret)
210 goto err5;
211
212 return 0;
213
214err5:
215 phy_driver_unregister(&ks8041_driver);
216err4:
217 phy_driver_unregister(&ks8737_driver);
218err3:
219 phy_driver_unregister(&ksz9021_driver);
220err2:
221 phy_driver_unregister(&ks8001_driver);
222err1:
223 return ret;
224} 187}
225 188
226static void __exit ksphy_exit(void) 189static void __exit ksphy_exit(void)
227{ 190{
228 phy_driver_unregister(&ks8001_driver); 191 phy_drivers_unregister(ksphy_driver,
229 phy_driver_unregister(&ks8737_driver); 192 ARRAY_SIZE(ksphy_driver));
230 phy_driver_unregister(&ksz9021_driver);
231 phy_driver_unregister(&ks8041_driver);
232 phy_driver_unregister(&ks8051_driver);
233} 193}
234 194
235module_init(ksphy_init); 195module_init(ksphy_init);
diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c
index 04bb8fcc0cb5..9a5f234d95b0 100644
--- a/drivers/net/phy/national.c
+++ b/drivers/net/phy/national.c
@@ -15,6 +15,8 @@
15 * 15 *
16 */ 16 */
17 17
18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
18#include <linux/kernel.h> 20#include <linux/kernel.h>
19#include <linux/module.h> 21#include <linux/module.h>
20#include <linux/mii.h> 22#include <linux/mii.h>
@@ -22,6 +24,8 @@
22#include <linux/phy.h> 24#include <linux/phy.h>
23#include <linux/netdevice.h> 25#include <linux/netdevice.h>
24 26
27#define DEBUG
28
25/* DP83865 phy identifier values */ 29/* DP83865 phy identifier values */
26#define DP83865_PHY_ID 0x20005c7a 30#define DP83865_PHY_ID 0x20005c7a
27 31
@@ -112,8 +116,8 @@ static void ns_10_base_t_hdx_loopack(struct phy_device *phydev, int disable)
112 ns_exp_write(phydev, 0x1c0, 116 ns_exp_write(phydev, 0x1c0,
113 ns_exp_read(phydev, 0x1c0) & 0xfffe); 117 ns_exp_read(phydev, 0x1c0) & 0xfffe);
114 118
115 printk(KERN_DEBUG "DP83865 PHY: 10BASE-T HDX loopback %s\n", 119 pr_debug("10BASE-T HDX loopback %s\n",
116 (ns_exp_read(phydev, 0x1c0) & 0x0001) ? "off" : "on"); 120 (ns_exp_read(phydev, 0x1c0) & 0x0001) ? "off" : "on");
117} 121}
118 122
119static int ns_config_init(struct phy_device *phydev) 123static int ns_config_init(struct phy_device *phydev)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3cbda0851f83..7ca2ff97c368 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -15,6 +15,9 @@
15 * option) any later version. 15 * option) any later version.
16 * 16 *
17 */ 17 */
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
18#include <linux/kernel.h> 21#include <linux/kernel.h>
19#include <linux/string.h> 22#include <linux/string.h>
20#include <linux/errno.h> 23#include <linux/errno.h>
@@ -32,6 +35,7 @@
32#include <linux/phy.h> 35#include <linux/phy.h>
33#include <linux/timer.h> 36#include <linux/timer.h>
34#include <linux/workqueue.h> 37#include <linux/workqueue.h>
38#include <linux/mdio.h>
35 39
36#include <linux/atomic.h> 40#include <linux/atomic.h>
37#include <asm/io.h> 41#include <asm/io.h>
@@ -44,18 +48,16 @@
44 */ 48 */
45void phy_print_status(struct phy_device *phydev) 49void phy_print_status(struct phy_device *phydev)
46{ 50{
47 pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev),
48 phydev->link ? "Up" : "Down");
49 if (phydev->link) 51 if (phydev->link)
50 printk(KERN_CONT " - %d/%s", phydev->speed, 52 pr_info("%s - Link is Up - %d/%s\n",
51 DUPLEX_FULL == phydev->duplex ? 53 dev_name(&phydev->dev),
52 "Full" : "Half"); 54 phydev->speed,
53 55 DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
54 printk(KERN_CONT "\n"); 56 else
57 pr_info("%s - Link is Down\n", dev_name(&phydev->dev));
55} 58}
56EXPORT_SYMBOL(phy_print_status); 59EXPORT_SYMBOL(phy_print_status);
57 60
58
59/** 61/**
60 * phy_clear_interrupt - Ack the phy device's interrupt 62 * phy_clear_interrupt - Ack the phy device's interrupt
61 * @phydev: the phy_device struct 63 * @phydev: the phy_device struct
@@ -482,9 +484,8 @@ static void phy_force_reduction(struct phy_device *phydev)
482 phydev->speed = settings[idx].speed; 484 phydev->speed = settings[idx].speed;
483 phydev->duplex = settings[idx].duplex; 485 phydev->duplex = settings[idx].duplex;
484 486
485 pr_info("Trying %d/%s\n", phydev->speed, 487 pr_info("Trying %d/%s\n",
486 DUPLEX_FULL == phydev->duplex ? 488 phydev->speed, DUPLEX_FULL == phydev->duplex ? "FULL" : "HALF");
487 "FULL" : "HALF");
488} 489}
489 490
490 491
@@ -598,9 +599,8 @@ int phy_start_interrupts(struct phy_device *phydev)
598 IRQF_SHARED, 599 IRQF_SHARED,
599 "phy_interrupt", 600 "phy_interrupt",
600 phydev) < 0) { 601 phydev) < 0) {
601 printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n", 602 pr_warn("%s: Can't get IRQ %d (PHY)\n",
602 phydev->bus->name, 603 phydev->bus->name, phydev->irq);
603 phydev->irq);
604 phydev->irq = PHY_POLL; 604 phydev->irq = PHY_POLL;
605 return 0; 605 return 0;
606 } 606 }
@@ -838,10 +838,10 @@ void phy_state_machine(struct work_struct *work)
838 838
839 phydev->autoneg = AUTONEG_DISABLE; 839 phydev->autoneg = AUTONEG_DISABLE;
840 840
841 pr_info("Trying %d/%s\n", phydev->speed, 841 pr_info("Trying %d/%s\n",
842 DUPLEX_FULL == 842 phydev->speed,
843 phydev->duplex ? 843 DUPLEX_FULL == phydev->duplex ?
844 "FULL" : "HALF"); 844 "FULL" : "HALF");
845 } 845 }
846 break; 846 break;
847 case PHY_NOLINK: 847 case PHY_NOLINK:
@@ -968,3 +968,283 @@ void phy_state_machine(struct work_struct *work)
968 968
969 schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ); 969 schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
970} 970}
971
972static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
973 int addr)
974{
975 /* Write the desired MMD Devad */
976 bus->write(bus, addr, MII_MMD_CTRL, devad);
977
978 /* Write the desired MMD register address */
979 bus->write(bus, addr, MII_MMD_DATA, prtad);
980
981 /* Select the Function : DATA with no post increment */
982 bus->write(bus, addr, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
983}
984
985/**
986 * phy_read_mmd_indirect - reads data from the MMD registers
987 * @bus: the target MII bus
988 * @prtad: MMD Address
989 * @devad: MMD DEVAD
990 * @addr: PHY address on the MII bus
991 *
992 * Description: it reads data from the MMD registers (clause 22 to access to
993 * clause 45) of the specified phy address.
994 * To read these register we have:
995 * 1) Write reg 13 // DEVAD
996 * 2) Write reg 14 // MMD Address
997 * 3) Write reg 13 // MMD Data Command for MMD DEVAD
998 * 3) Read reg 14 // Read MMD data
999 */
1000static int phy_read_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
1001 int addr)
1002{
1003 u32 ret;
1004
1005 mmd_phy_indirect(bus, prtad, devad, addr);
1006
1007 /* Read the content of the MMD's selected register */
1008 ret = bus->read(bus, addr, MII_MMD_DATA);
1009
1010 return ret;
1011}
1012
1013/**
1014 * phy_write_mmd_indirect - writes data to the MMD registers
1015 * @bus: the target MII bus
1016 * @prtad: MMD Address
1017 * @devad: MMD DEVAD
1018 * @addr: PHY address on the MII bus
1019 * @data: data to write in the MMD register
1020 *
1021 * Description: Write data from the MMD registers of the specified
1022 * phy address.
1023 * To write these register we have:
1024 * 1) Write reg 13 // DEVAD
1025 * 2) Write reg 14 // MMD Address
1026 * 3) Write reg 13 // MMD Data Command for MMD DEVAD
1027 * 3) Write reg 14 // Write MMD data
1028 */
1029static void phy_write_mmd_indirect(struct mii_bus *bus, int prtad, int devad,
1030 int addr, u32 data)
1031{
1032 mmd_phy_indirect(bus, prtad, devad, addr);
1033
1034 /* Write the data into MMD's selected register */
1035 bus->write(bus, addr, MII_MMD_DATA, data);
1036}
1037
1038static u32 phy_eee_to_adv(u16 eee_adv)
1039{
1040 u32 adv = 0;
1041
1042 if (eee_adv & MDIO_EEE_100TX)
1043 adv |= ADVERTISED_100baseT_Full;
1044 if (eee_adv & MDIO_EEE_1000T)
1045 adv |= ADVERTISED_1000baseT_Full;
1046 if (eee_adv & MDIO_EEE_10GT)
1047 adv |= ADVERTISED_10000baseT_Full;
1048 if (eee_adv & MDIO_EEE_1000KX)
1049 adv |= ADVERTISED_1000baseKX_Full;
1050 if (eee_adv & MDIO_EEE_10GKX4)
1051 adv |= ADVERTISED_10000baseKX4_Full;
1052 if (eee_adv & MDIO_EEE_10GKR)
1053 adv |= ADVERTISED_10000baseKR_Full;
1054
1055 return adv;
1056}
1057
1058static u32 phy_eee_to_supported(u16 eee_caported)
1059{
1060 u32 supported = 0;
1061
1062 if (eee_caported & MDIO_EEE_100TX)
1063 supported |= SUPPORTED_100baseT_Full;
1064 if (eee_caported & MDIO_EEE_1000T)
1065 supported |= SUPPORTED_1000baseT_Full;
1066 if (eee_caported & MDIO_EEE_10GT)
1067 supported |= SUPPORTED_10000baseT_Full;
1068 if (eee_caported & MDIO_EEE_1000KX)
1069 supported |= SUPPORTED_1000baseKX_Full;
1070 if (eee_caported & MDIO_EEE_10GKX4)
1071 supported |= SUPPORTED_10000baseKX4_Full;
1072 if (eee_caported & MDIO_EEE_10GKR)
1073 supported |= SUPPORTED_10000baseKR_Full;
1074
1075 return supported;
1076}
1077
1078static u16 phy_adv_to_eee(u32 adv)
1079{
1080 u16 reg = 0;
1081
1082 if (adv & ADVERTISED_100baseT_Full)
1083 reg |= MDIO_EEE_100TX;
1084 if (adv & ADVERTISED_1000baseT_Full)
1085 reg |= MDIO_EEE_1000T;
1086 if (adv & ADVERTISED_10000baseT_Full)
1087 reg |= MDIO_EEE_10GT;
1088 if (adv & ADVERTISED_1000baseKX_Full)
1089 reg |= MDIO_EEE_1000KX;
1090 if (adv & ADVERTISED_10000baseKX4_Full)
1091 reg |= MDIO_EEE_10GKX4;
1092 if (adv & ADVERTISED_10000baseKR_Full)
1093 reg |= MDIO_EEE_10GKR;
1094
1095 return reg;
1096}
1097
1098/**
1099 * phy_init_eee - init and check the EEE feature
1100 * @phydev: target phy_device struct
1101 * @clk_stop_enable: PHY may stop the clock during LPI
1102 *
1103 * Description: it checks if the Energy-Efficient Ethernet (EEE)
1104 * is supported by looking at the MMD registers 3.20 and 7.60/61
1105 * and it programs the MMD register 3.0 setting the "Clock stop enable"
1106 * bit if required.
1107 */
1108int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
1109{
1110 int ret = -EPROTONOSUPPORT;
1111
1112 /* According to 802.3az,the EEE is supported only in full duplex-mode.
1113 * Also EEE feature is active when core is operating with MII, GMII
1114 * or RGMII.
1115 */
1116 if ((phydev->duplex == DUPLEX_FULL) &&
1117 ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
1118 (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
1119 (phydev->interface == PHY_INTERFACE_MODE_RGMII))) {
1120 int eee_lp, eee_cap, eee_adv;
1121 u32 lp, cap, adv;
1122 int idx, status;
1123
1124 /* Read phy status to properly get the right settings */
1125 status = phy_read_status(phydev);
1126 if (status)
1127 return status;
1128
1129 /* First check if the EEE ability is supported */
1130 eee_cap = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE,
1131 MDIO_MMD_PCS, phydev->addr);
1132 if (eee_cap < 0)
1133 return eee_cap;
1134
1135 cap = phy_eee_to_supported(eee_cap);
1136 if (!cap)
1137 goto eee_exit;
1138
1139 /* Check which link settings negotiated and verify it in
1140 * the EEE advertising registers.
1141 */
1142 eee_lp = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE,
1143 MDIO_MMD_AN, phydev->addr);
1144 if (eee_lp < 0)
1145 return eee_lp;
1146
1147 eee_adv = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV,
1148 MDIO_MMD_AN, phydev->addr);
1149 if (eee_adv < 0)
1150 return eee_adv;
1151
1152 adv = phy_eee_to_adv(eee_adv);
1153 lp = phy_eee_to_adv(eee_lp);
1154 idx = phy_find_setting(phydev->speed, phydev->duplex);
1155 if ((lp & adv & settings[idx].setting))
1156 goto eee_exit;
1157
1158 if (clk_stop_enable) {
1159 /* Configure the PHY to stop receiving xMII
1160 * clock while it is signaling LPI.
1161 */
1162 int val = phy_read_mmd_indirect(phydev->bus, MDIO_CTRL1,
1163 MDIO_MMD_PCS,
1164 phydev->addr);
1165 if (val < 0)
1166 return val;
1167
1168 val |= MDIO_PCS_CTRL1_CLKSTOP_EN;
1169 phy_write_mmd_indirect(phydev->bus, MDIO_CTRL1,
1170 MDIO_MMD_PCS, phydev->addr, val);
1171 }
1172
1173 ret = 0; /* EEE supported */
1174 }
1175
1176eee_exit:
1177 return ret;
1178}
1179EXPORT_SYMBOL(phy_init_eee);
1180
1181/**
1182 * phy_get_eee_err - report the EEE wake error count
1183 * @phydev: target phy_device struct
1184 *
1185 * Description: it is to report the number of time where the PHY
1186 * failed to complete its normal wake sequence.
1187 */
1188int phy_get_eee_err(struct phy_device *phydev)
1189{
1190 return phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_WK_ERR,
1191 MDIO_MMD_PCS, phydev->addr);
1192
1193}
1194EXPORT_SYMBOL(phy_get_eee_err);
1195
1196/**
1197 * phy_ethtool_get_eee - get EEE supported and status
1198 * @phydev: target phy_device struct
1199 * @data: ethtool_eee data
1200 *
1201 * Description: it reportes the Supported/Advertisement/LP Advertisement
1202 * capabilities.
1203 */
1204int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data)
1205{
1206 int val;
1207
1208 /* Get Supported EEE */
1209 val = phy_read_mmd_indirect(phydev->bus, MDIO_PCS_EEE_ABLE,
1210 MDIO_MMD_PCS, phydev->addr);
1211 if (val < 0)
1212 return val;
1213 data->supported = phy_eee_to_supported(val);
1214
1215 /* Get advertisement EEE */
1216 val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV,
1217 MDIO_MMD_AN, phydev->addr);
1218 if (val < 0)
1219 return val;
1220 data->advertised = phy_eee_to_adv(val);
1221
1222 /* Get LP advertisement EEE */
1223 val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE,
1224 MDIO_MMD_AN, phydev->addr);
1225 if (val < 0)
1226 return val;
1227 data->lp_advertised = phy_eee_to_adv(val);
1228
1229 return 0;
1230}
1231EXPORT_SYMBOL(phy_ethtool_get_eee);
1232
1233/**
1234 * phy_ethtool_set_eee - set EEE supported and status
1235 * @phydev: target phy_device struct
1236 * @data: ethtool_eee data
1237 *
1238 * Description: it is to program the Advertisement EEE register.
1239 */
1240int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
1241{
1242 int val;
1243
1244 val = phy_adv_to_eee(data->advertised);
1245 phy_write_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN,
1246 phydev->addr, val);
1247
1248 return 0;
1249}
1250EXPORT_SYMBOL(phy_ethtool_set_eee);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index de86a5582224..8af46e88a181 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -14,6 +14,9 @@
14 * option) any later version. 14 * option) any later version.
15 * 15 *
16 */ 16 */
17
18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
17#include <linux/kernel.h> 20#include <linux/kernel.h>
18#include <linux/string.h> 21#include <linux/string.h>
19#include <linux/errno.h> 22#include <linux/errno.h>
@@ -149,8 +152,8 @@ int phy_scan_fixups(struct phy_device *phydev)
149} 152}
150EXPORT_SYMBOL(phy_scan_fixups); 153EXPORT_SYMBOL(phy_scan_fixups);
151 154
152static struct phy_device* phy_device_create(struct mii_bus *bus, 155struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
153 int addr, int phy_id) 156 bool is_c45, struct phy_c45_device_ids *c45_ids)
154{ 157{
155 struct phy_device *dev; 158 struct phy_device *dev;
156 159
@@ -171,8 +174,11 @@ static struct phy_device* phy_device_create(struct mii_bus *bus,
171 174
172 dev->autoneg = AUTONEG_ENABLE; 175 dev->autoneg = AUTONEG_ENABLE;
173 176
177 dev->is_c45 = is_c45;
174 dev->addr = addr; 178 dev->addr = addr;
175 dev->phy_id = phy_id; 179 dev->phy_id = phy_id;
180 if (c45_ids)
181 dev->c45_ids = *c45_ids;
176 dev->bus = bus; 182 dev->bus = bus;
177 dev->dev.parent = bus->parent; 183 dev->dev.parent = bus->parent;
178 dev->dev.bus = &mdio_bus_type; 184 dev->dev.bus = &mdio_bus_type;
@@ -197,20 +203,99 @@ static struct phy_device* phy_device_create(struct mii_bus *bus,
197 203
198 return dev; 204 return dev;
199} 205}
206EXPORT_SYMBOL(phy_device_create);
207
208/**
209 * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs.
210 * @bus: the target MII bus
211 * @addr: PHY address on the MII bus
212 * @phy_id: where to store the ID retrieved.
213 * @c45_ids: where to store the c45 ID information.
214 *
215 * If the PHY devices-in-package appears to be valid, it and the
216 * corresponding identifiers are stored in @c45_ids, zero is stored
217 * in @phy_id. Otherwise 0xffffffff is stored in @phy_id. Returns
218 * zero on success.
219 *
220 */
221static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id,
222 struct phy_c45_device_ids *c45_ids) {
223 int phy_reg;
224 int i, reg_addr;
225 const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
226
227 /* Find first non-zero Devices In package. Device
228 * zero is reserved, so don't probe it.
229 */
230 for (i = 1;
231 i < num_ids && c45_ids->devices_in_package == 0;
232 i++) {
233 reg_addr = MII_ADDR_C45 | i << 16 | 6;
234 phy_reg = mdiobus_read(bus, addr, reg_addr);
235 if (phy_reg < 0)
236 return -EIO;
237 c45_ids->devices_in_package = (phy_reg & 0xffff) << 16;
238
239 reg_addr = MII_ADDR_C45 | i << 16 | 5;
240 phy_reg = mdiobus_read(bus, addr, reg_addr);
241 if (phy_reg < 0)
242 return -EIO;
243 c45_ids->devices_in_package |= (phy_reg & 0xffff);
244
245 /* If mostly Fs, there is no device there,
246 * let's get out of here.
247 */
248 if ((c45_ids->devices_in_package & 0x1fffffff) == 0x1fffffff) {
249 *phy_id = 0xffffffff;
250 return 0;
251 }
252 }
253
254 /* Now probe Device Identifiers for each device present. */
255 for (i = 1; i < num_ids; i++) {
256 if (!(c45_ids->devices_in_package & (1 << i)))
257 continue;
258
259 reg_addr = MII_ADDR_C45 | i << 16 | MII_PHYSID1;
260 phy_reg = mdiobus_read(bus, addr, reg_addr);
261 if (phy_reg < 0)
262 return -EIO;
263 c45_ids->device_ids[i] = (phy_reg & 0xffff) << 16;
264
265 reg_addr = MII_ADDR_C45 | i << 16 | MII_PHYSID2;
266 phy_reg = mdiobus_read(bus, addr, reg_addr);
267 if (phy_reg < 0)
268 return -EIO;
269 c45_ids->device_ids[i] |= (phy_reg & 0xffff);
270 }
271 *phy_id = 0;
272 return 0;
273}
200 274
201/** 275/**
202 * get_phy_id - reads the specified addr for its ID. 276 * get_phy_id - reads the specified addr for its ID.
203 * @bus: the target MII bus 277 * @bus: the target MII bus
204 * @addr: PHY address on the MII bus 278 * @addr: PHY address on the MII bus
205 * @phy_id: where to store the ID retrieved. 279 * @phy_id: where to store the ID retrieved.
280 * @is_c45: If true the PHY uses the 802.3 clause 45 protocol
281 * @c45_ids: where to store the c45 ID information.
282 *
283 * Description: In the case of a 802.3-c22 PHY, reads the ID registers
284 * of the PHY at @addr on the @bus, stores it in @phy_id and returns
285 * zero on success.
286 *
287 * In the case of a 802.3-c45 PHY, get_phy_c45_ids() is invoked, and
288 * its return value is in turn returned.
206 * 289 *
207 * Description: Reads the ID registers of the PHY at @addr on the
208 * @bus, stores it in @phy_id and returns zero on success.
209 */ 290 */
210static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id) 291static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id,
292 bool is_c45, struct phy_c45_device_ids *c45_ids)
211{ 293{
212 int phy_reg; 294 int phy_reg;
213 295
296 if (is_c45)
297 return get_phy_c45_ids(bus, addr, phy_id, c45_ids);
298
214 /* Grab the bits from PHYIR1, and put them 299 /* Grab the bits from PHYIR1, and put them
215 * in the upper half */ 300 * in the upper half */
216 phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); 301 phy_reg = mdiobus_read(bus, addr, MII_PHYSID1);
@@ -235,17 +320,19 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
235 * get_phy_device - reads the specified PHY device and returns its @phy_device struct 320 * get_phy_device - reads the specified PHY device and returns its @phy_device struct
236 * @bus: the target MII bus 321 * @bus: the target MII bus
237 * @addr: PHY address on the MII bus 322 * @addr: PHY address on the MII bus
323 * @is_c45: If true the PHY uses the 802.3 clause 45 protocol
238 * 324 *
239 * Description: Reads the ID registers of the PHY at @addr on the 325 * Description: Reads the ID registers of the PHY at @addr on the
240 * @bus, then allocates and returns the phy_device to represent it. 326 * @bus, then allocates and returns the phy_device to represent it.
241 */ 327 */
242struct phy_device * get_phy_device(struct mii_bus *bus, int addr) 328struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
243{ 329{
330 struct phy_c45_device_ids c45_ids = {0};
244 struct phy_device *dev = NULL; 331 struct phy_device *dev = NULL;
245 u32 phy_id; 332 u32 phy_id = 0;
246 int r; 333 int r;
247 334
248 r = get_phy_id(bus, addr, &phy_id); 335 r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids);
249 if (r) 336 if (r)
250 return ERR_PTR(r); 337 return ERR_PTR(r);
251 338
@@ -253,7 +340,7 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
253 if ((phy_id & 0x1fffffff) == 0x1fffffff) 340 if ((phy_id & 0x1fffffff) == 0x1fffffff)
254 return NULL; 341 return NULL;
255 342
256 dev = phy_device_create(bus, addr, phy_id); 343 dev = phy_device_create(bus, addr, phy_id, is_c45, &c45_ids);
257 344
258 return dev; 345 return dev;
259} 346}
@@ -446,6 +533,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
446 /* Assume that if there is no driver, that it doesn't 533 /* Assume that if there is no driver, that it doesn't
447 * exist, and we should use the genphy driver. */ 534 * exist, and we should use the genphy driver. */
448 if (NULL == d->driver) { 535 if (NULL == d->driver) {
536 if (phydev->is_c45) {
537 pr_err("No driver for phy %x\n", phydev->phy_id);
538 return -ENODEV;
539 }
540
449 d->driver = &genphy_driver.driver; 541 d->driver = &genphy_driver.driver;
450 542
451 err = d->driver->probe(d); 543 err = d->driver->probe(d);
@@ -975,8 +1067,8 @@ int phy_driver_register(struct phy_driver *new_driver)
975 retval = driver_register(&new_driver->driver); 1067 retval = driver_register(&new_driver->driver);
976 1068
977 if (retval) { 1069 if (retval) {
978 printk(KERN_ERR "%s: Error %d in registering driver\n", 1070 pr_err("%s: Error %d in registering driver\n",
979 new_driver->name, retval); 1071 new_driver->name, retval);
980 1072
981 return retval; 1073 return retval;
982 } 1074 }
@@ -987,12 +1079,37 @@ int phy_driver_register(struct phy_driver *new_driver)
987} 1079}
988EXPORT_SYMBOL(phy_driver_register); 1080EXPORT_SYMBOL(phy_driver_register);
989 1081
1082int phy_drivers_register(struct phy_driver *new_driver, int n)
1083{
1084 int i, ret = 0;
1085
1086 for (i = 0; i < n; i++) {
1087 ret = phy_driver_register(new_driver + i);
1088 if (ret) {
1089 while (i-- > 0)
1090 phy_driver_unregister(new_driver + i);
1091 break;
1092 }
1093 }
1094 return ret;
1095}
1096EXPORT_SYMBOL(phy_drivers_register);
1097
990void phy_driver_unregister(struct phy_driver *drv) 1098void phy_driver_unregister(struct phy_driver *drv)
991{ 1099{
992 driver_unregister(&drv->driver); 1100 driver_unregister(&drv->driver);
993} 1101}
994EXPORT_SYMBOL(phy_driver_unregister); 1102EXPORT_SYMBOL(phy_driver_unregister);
995 1103
1104void phy_drivers_unregister(struct phy_driver *drv, int n)
1105{
1106 int i;
1107 for (i = 0; i < n; i++) {
1108 phy_driver_unregister(drv + i);
1109 }
1110}
1111EXPORT_SYMBOL(phy_drivers_unregister);
1112
996static struct phy_driver genphy_driver = { 1113static struct phy_driver genphy_driver = {
997 .phy_id = 0xffffffff, 1114 .phy_id = 0xffffffff,
998 .phy_id_mask = 0xffffffff, 1115 .phy_id_mask = 0xffffffff,
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index f414ffb5b728..72f93470ea35 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -65,11 +65,7 @@ static struct phy_driver rtl821x_driver = {
65 65
66static int __init realtek_init(void) 66static int __init realtek_init(void)
67{ 67{
68 int ret; 68 return phy_driver_register(&rtl821x_driver);
69
70 ret = phy_driver_register(&rtl821x_driver);
71
72 return ret;
73} 69}
74 70
75static void __exit realtek_exit(void) 71static void __exit realtek_exit(void)
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index fc3e7e96c88c..6d6192316b30 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -12,7 +12,7 @@
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. 13 * option) any later version.
14 * 14 *
15 * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@smsc.com 15 * Support added for SMSC LAN8187 and LAN8700 by steve.glendinning@shawell.net
16 * 16 *
17 */ 17 */
18 18
@@ -61,7 +61,8 @@ static int lan911x_config_init(struct phy_device *phydev)
61 return smsc_phy_ack_interrupt(phydev); 61 return smsc_phy_ack_interrupt(phydev);
62} 62}
63 63
64static struct phy_driver lan83c185_driver = { 64static struct phy_driver smsc_phy_driver[] = {
65{
65 .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */ 66 .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
66 .phy_id_mask = 0xfffffff0, 67 .phy_id_mask = 0xfffffff0,
67 .name = "SMSC LAN83C185", 68 .name = "SMSC LAN83C185",
@@ -83,9 +84,7 @@ static struct phy_driver lan83c185_driver = {
83 .resume = genphy_resume, 84 .resume = genphy_resume,
84 85
85 .driver = { .owner = THIS_MODULE, } 86 .driver = { .owner = THIS_MODULE, }
86}; 87}, {
87
88static struct phy_driver lan8187_driver = {
89 .phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */ 88 .phy_id = 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
90 .phy_id_mask = 0xfffffff0, 89 .phy_id_mask = 0xfffffff0,
91 .name = "SMSC LAN8187", 90 .name = "SMSC LAN8187",
@@ -107,9 +106,7 @@ static struct phy_driver lan8187_driver = {
107 .resume = genphy_resume, 106 .resume = genphy_resume,
108 107
109 .driver = { .owner = THIS_MODULE, } 108 .driver = { .owner = THIS_MODULE, }
110}; 109}, {
111
112static struct phy_driver lan8700_driver = {
113 .phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */ 110 .phy_id = 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
114 .phy_id_mask = 0xfffffff0, 111 .phy_id_mask = 0xfffffff0,
115 .name = "SMSC LAN8700", 112 .name = "SMSC LAN8700",
@@ -131,9 +128,7 @@ static struct phy_driver lan8700_driver = {
131 .resume = genphy_resume, 128 .resume = genphy_resume,
132 129
133 .driver = { .owner = THIS_MODULE, } 130 .driver = { .owner = THIS_MODULE, }
134}; 131}, {
135
136static struct phy_driver lan911x_int_driver = {
137 .phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */ 132 .phy_id = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
138 .phy_id_mask = 0xfffffff0, 133 .phy_id_mask = 0xfffffff0,
139 .name = "SMSC LAN911x Internal PHY", 134 .name = "SMSC LAN911x Internal PHY",
@@ -155,9 +150,7 @@ static struct phy_driver lan911x_int_driver = {
155 .resume = genphy_resume, 150 .resume = genphy_resume,
156 151
157 .driver = { .owner = THIS_MODULE, } 152 .driver = { .owner = THIS_MODULE, }
158}; 153}, {
159
160static struct phy_driver lan8710_driver = {
161 .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */ 154 .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
162 .phy_id_mask = 0xfffffff0, 155 .phy_id_mask = 0xfffffff0,
163 .name = "SMSC LAN8710/LAN8720", 156 .name = "SMSC LAN8710/LAN8720",
@@ -179,53 +172,18 @@ static struct phy_driver lan8710_driver = {
179 .resume = genphy_resume, 172 .resume = genphy_resume,
180 173
181 .driver = { .owner = THIS_MODULE, } 174 .driver = { .owner = THIS_MODULE, }
182}; 175} };
183 176
184static int __init smsc_init(void) 177static int __init smsc_init(void)
185{ 178{
186 int ret; 179 return phy_drivers_register(smsc_phy_driver,
187 180 ARRAY_SIZE(smsc_phy_driver));
188 ret = phy_driver_register (&lan83c185_driver);
189 if (ret)
190 goto err1;
191
192 ret = phy_driver_register (&lan8187_driver);
193 if (ret)
194 goto err2;
195
196 ret = phy_driver_register (&lan8700_driver);
197 if (ret)
198 goto err3;
199
200 ret = phy_driver_register (&lan911x_int_driver);
201 if (ret)
202 goto err4;
203
204 ret = phy_driver_register (&lan8710_driver);
205 if (ret)
206 goto err5;
207
208 return 0;
209
210err5:
211 phy_driver_unregister (&lan911x_int_driver);
212err4:
213 phy_driver_unregister (&lan8700_driver);
214err3:
215 phy_driver_unregister (&lan8187_driver);
216err2:
217 phy_driver_unregister (&lan83c185_driver);
218err1:
219 return ret;
220} 181}
221 182
222static void __exit smsc_exit(void) 183static void __exit smsc_exit(void)
223{ 184{
224 phy_driver_unregister (&lan8710_driver); 185 return phy_drivers_unregister(smsc_phy_driver,
225 phy_driver_unregister (&lan911x_int_driver); 186 ARRAY_SIZE(smsc_phy_driver));
226 phy_driver_unregister (&lan8700_driver);
227 phy_driver_unregister (&lan8187_driver);
228 phy_driver_unregister (&lan83c185_driver);
229} 187}
230 188
231MODULE_DESCRIPTION("SMSC PHY driver"); 189MODULE_DESCRIPTION("SMSC PHY driver");
diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
index 4eb98bc52a0a..1c3abce78b6a 100644
--- a/drivers/net/phy/spi_ks8995.c
+++ b/drivers/net/phy/spi_ks8995.c
@@ -11,6 +11,8 @@
11 * by the Free Software Foundation. 11 * by the Free Software Foundation.
12 */ 12 */
13 13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
14#include <linux/types.h> 16#include <linux/types.h>
15#include <linux/kernel.h> 17#include <linux/kernel.h>
16#include <linux/init.h> 18#include <linux/init.h>
@@ -356,7 +358,7 @@ static struct spi_driver ks8995_driver = {
356 358
357static int __init ks8995_init(void) 359static int __init ks8995_init(void)
358{ 360{
359 printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n"); 361 pr_info(DRV_DESC " version " DRV_VERSION "\n");
360 362
361 return spi_register_driver(&ks8995_driver); 363 return spi_register_driver(&ks8995_driver);
362} 364}
diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c
index 187a2fa814f2..5e1eb138916f 100644
--- a/drivers/net/phy/ste10Xp.c
+++ b/drivers/net/phy/ste10Xp.c
@@ -81,7 +81,8 @@ static int ste10Xp_ack_interrupt(struct phy_device *phydev)
81 return 0; 81 return 0;
82} 82}
83 83
84static struct phy_driver ste101p_pdriver = { 84static struct phy_driver ste10xp_pdriver[] = {
85{
85 .phy_id = STE101P_PHY_ID, 86 .phy_id = STE101P_PHY_ID,
86 .phy_id_mask = 0xfffffff0, 87 .phy_id_mask = 0xfffffff0,
87 .name = "STe101p", 88 .name = "STe101p",
@@ -95,9 +96,7 @@ static struct phy_driver ste101p_pdriver = {
95 .suspend = genphy_suspend, 96 .suspend = genphy_suspend,
96 .resume = genphy_resume, 97 .resume = genphy_resume,
97 .driver = {.owner = THIS_MODULE,} 98 .driver = {.owner = THIS_MODULE,}
98}; 99}, {
99
100static struct phy_driver ste100p_pdriver = {
101 .phy_id = STE100P_PHY_ID, 100 .phy_id = STE100P_PHY_ID,
102 .phy_id_mask = 0xffffffff, 101 .phy_id_mask = 0xffffffff,
103 .name = "STe100p", 102 .name = "STe100p",
@@ -111,22 +110,18 @@ static struct phy_driver ste100p_pdriver = {
111 .suspend = genphy_suspend, 110 .suspend = genphy_suspend,
112 .resume = genphy_resume, 111 .resume = genphy_resume,
113 .driver = {.owner = THIS_MODULE,} 112 .driver = {.owner = THIS_MODULE,}
114}; 113} };
115 114
116static int __init ste10Xp_init(void) 115static int __init ste10Xp_init(void)
117{ 116{
118 int retval; 117 return phy_drivers_register(ste10xp_pdriver,
119 118 ARRAY_SIZE(ste10xp_pdriver));
120 retval = phy_driver_register(&ste100p_pdriver);
121 if (retval < 0)
122 return retval;
123 return phy_driver_register(&ste101p_pdriver);
124} 119}
125 120
126static void __exit ste10Xp_exit(void) 121static void __exit ste10Xp_exit(void)
127{ 122{
128 phy_driver_unregister(&ste100p_pdriver); 123 phy_drivers_unregister(ste10xp_pdriver,
129 phy_driver_unregister(&ste101p_pdriver); 124 ARRAY_SIZE(ste10xp_pdriver));
130} 125}
131 126
132module_init(ste10Xp_init); 127module_init(ste10Xp_init);
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 0ec8e09cc2ac..2585c383e623 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -138,21 +138,6 @@ static int vsc82xx_config_intr(struct phy_device *phydev)
138 return err; 138 return err;
139} 139}
140 140
141/* Vitesse 824x */
142static struct phy_driver vsc8244_driver = {
143 .phy_id = PHY_ID_VSC8244,
144 .name = "Vitesse VSC8244",
145 .phy_id_mask = 0x000fffc0,
146 .features = PHY_GBIT_FEATURES,
147 .flags = PHY_HAS_INTERRUPT,
148 .config_init = &vsc824x_config_init,
149 .config_aneg = &genphy_config_aneg,
150 .read_status = &genphy_read_status,
151 .ack_interrupt = &vsc824x_ack_interrupt,
152 .config_intr = &vsc82xx_config_intr,
153 .driver = { .owner = THIS_MODULE,},
154};
155
156static int vsc8221_config_init(struct phy_device *phydev) 141static int vsc8221_config_init(struct phy_device *phydev)
157{ 142{
158 int err; 143 int err;
@@ -165,8 +150,22 @@ static int vsc8221_config_init(struct phy_device *phydev)
165 Options are 802.3Z SerDes or SGMII */ 150 Options are 802.3Z SerDes or SGMII */
166} 151}
167 152
168/* Vitesse 8221 */ 153/* Vitesse 824x */
169static struct phy_driver vsc8221_driver = { 154static struct phy_driver vsc82xx_driver[] = {
155{
156 .phy_id = PHY_ID_VSC8244,
157 .name = "Vitesse VSC8244",
158 .phy_id_mask = 0x000fffc0,
159 .features = PHY_GBIT_FEATURES,
160 .flags = PHY_HAS_INTERRUPT,
161 .config_init = &vsc824x_config_init,
162 .config_aneg = &genphy_config_aneg,
163 .read_status = &genphy_read_status,
164 .ack_interrupt = &vsc824x_ack_interrupt,
165 .config_intr = &vsc82xx_config_intr,
166 .driver = { .owner = THIS_MODULE,},
167}, {
168 /* Vitesse 8221 */
170 .phy_id = PHY_ID_VSC8221, 169 .phy_id = PHY_ID_VSC8221,
171 .phy_id_mask = 0x000ffff0, 170 .phy_id_mask = 0x000ffff0,
172 .name = "Vitesse VSC8221", 171 .name = "Vitesse VSC8221",
@@ -177,26 +176,19 @@ static struct phy_driver vsc8221_driver = {
177 .read_status = &genphy_read_status, 176 .read_status = &genphy_read_status,
178 .ack_interrupt = &vsc824x_ack_interrupt, 177 .ack_interrupt = &vsc824x_ack_interrupt,
179 .config_intr = &vsc82xx_config_intr, 178 .config_intr = &vsc82xx_config_intr,
180 .driver = { .owner = THIS_MODULE,}, 179 .driver = { .owner = THIS_MODULE,},
181}; 180} };
182 181
183static int __init vsc82xx_init(void) 182static int __init vsc82xx_init(void)
184{ 183{
185 int err; 184 return phy_drivers_register(vsc82xx_driver,
186 185 ARRAY_SIZE(vsc82xx_driver));
187 err = phy_driver_register(&vsc8244_driver);
188 if (err < 0)
189 return err;
190 err = phy_driver_register(&vsc8221_driver);
191 if (err < 0)
192 phy_driver_unregister(&vsc8244_driver);
193 return err;
194} 186}
195 187
196static void __exit vsc82xx_exit(void) 188static void __exit vsc82xx_exit(void)
197{ 189{
198 phy_driver_unregister(&vsc8244_driver); 190 return phy_drivers_unregister(vsc82xx_driver,
199 phy_driver_unregister(&vsc8221_driver); 191 ARRAY_SIZE(vsc82xx_driver));
200} 192}
201 193
202module_init(vsc82xx_init); 194module_init(vsc82xx_init);