aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorDavid Daney <david.daney@cavium.com>2016-03-11 12:53:10 -0500
committerDavid S. Miller <davem@davemloft.net>2016-03-14 15:27:22 -0400
commit1eefee901fca0208b8a56f20cdc134e2b8638ae7 (patch)
treee8f32fb9b65e392349d1462c45d0f527c8c2f3d0 /drivers/net/phy
parent5fc7cf179449502ad4ad67845ded2df94b680de2 (diff)
phy: mdio-octeon: Refactor into two files/modules
A follow-on patch uses PCI probing to find the Thunder MDIO hardware. In preparation for this, split out the common code into a new file mdio-cavium.c, which will be used by both the existing OCTEON driver, and the new Thunder PCI based driver. As part of the refactoring simplify the struct cavium_mdiobus by removing fields that are only ever used in the probe function and can just as well be local variables. Use readq/writeq in preference to readq_relaxed/writeq_relaxed as the relaxed form was an optimization for an early chip revision, and the MDIO drivers are not performance bottlenecks that need optimization in the first place. Signed-off-by: David Daney <david.daney@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/Kconfig11
-rw-r--r--drivers/net/phy/Makefile1
-rw-r--r--drivers/net/phy/mdio-cavium.c149
-rw-r--r--drivers/net/phy/mdio-cavium.h119
-rw-r--r--drivers/net/phy/mdio-octeon.c280
5 files changed, 292 insertions, 268 deletions
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index f0a77020037a..40faec9f3b0b 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -183,15 +183,18 @@ config MDIO_GPIO
183 To compile this driver as a module, choose M here: the module 183 To compile this driver as a module, choose M here: the module
184 will be called mdio-gpio. 184 will be called mdio-gpio.
185 185
186config MDIO_CAVIUM
187 tristate
188
186config MDIO_OCTEON 189config MDIO_OCTEON
187 tristate "Support for MDIO buses on Octeon and ThunderX SOCs" 190 tristate "Support for MDIO buses on Octeon and some ThunderX SOCs"
188 depends on 64BIT 191 depends on 64BIT
189 depends on HAS_IOMEM 192 depends on HAS_IOMEM
193 select MDIO_CAVIUM
190 help 194 help
191
192 This module provides a driver for the Octeon and ThunderX MDIO 195 This module provides a driver for the Octeon and ThunderX MDIO
193 busses. It is required by the Octeon and ThunderX ethernet device 196 buses. It is required by the Octeon and ThunderX ethernet device
194 drivers. 197 drivers on some systems.
195 198
196config MDIO_SUN4I 199config MDIO_SUN4I
197 tristate "Allwinner sun4i MDIO interface support" 200 tristate "Allwinner sun4i MDIO interface support"
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 680e88f9915a..041b3d977d31 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_DP83867_PHY) += dp83867.o
31obj-$(CONFIG_STE10XP) += ste10Xp.o 31obj-$(CONFIG_STE10XP) += ste10Xp.o
32obj-$(CONFIG_MICREL_PHY) += micrel.o 32obj-$(CONFIG_MICREL_PHY) += micrel.o
33obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o 33obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
34obj-$(CONFIG_MDIO_CAVIUM) += mdio-cavium.o
34obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o 35obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
35obj-$(CONFIG_AT803X_PHY) += at803x.o 36obj-$(CONFIG_AT803X_PHY) += at803x.o
36obj-$(CONFIG_AMD_PHY) += amd.o 37obj-$(CONFIG_AMD_PHY) += amd.o
diff --git a/drivers/net/phy/mdio-cavium.c b/drivers/net/phy/mdio-cavium.c
new file mode 100644
index 000000000000..e796ee121eac
--- /dev/null
+++ b/drivers/net/phy/mdio-cavium.c
@@ -0,0 +1,149 @@
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) 2009-2016 Cavium, Inc.
7 */
8
9#include <linux/delay.h>
10#include <linux/module.h>
11#include <linux/phy.h>
12#include <linux/io.h>
13
14#include "mdio-cavium.h"
15
16static void cavium_mdiobus_set_mode(struct cavium_mdiobus *p,
17 enum cavium_mdiobus_mode m)
18{
19 union cvmx_smix_clk smi_clk;
20
21 if (m == p->mode)
22 return;
23
24 smi_clk.u64 = oct_mdio_readq(p->register_base + SMI_CLK);
25 smi_clk.s.mode = (m == C45) ? 1 : 0;
26 smi_clk.s.preamble = 1;
27 oct_mdio_writeq(smi_clk.u64, p->register_base + SMI_CLK);
28 p->mode = m;
29}
30
31static int cavium_mdiobus_c45_addr(struct cavium_mdiobus *p,
32 int phy_id, int regnum)
33{
34 union cvmx_smix_cmd smi_cmd;
35 union cvmx_smix_wr_dat smi_wr;
36 int timeout = 1000;
37
38 cavium_mdiobus_set_mode(p, C45);
39
40 smi_wr.u64 = 0;
41 smi_wr.s.dat = regnum & 0xffff;
42 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
43
44 regnum = (regnum >> 16) & 0x1f;
45
46 smi_cmd.u64 = 0;
47 smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_45_ADDRESS */
48 smi_cmd.s.phy_adr = phy_id;
49 smi_cmd.s.reg_adr = regnum;
50 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
51
52 do {
53 /* Wait 1000 clocks so we don't saturate the RSL bus
54 * doing reads.
55 */
56 __delay(1000);
57 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
58 } while (smi_wr.s.pending && --timeout);
59
60 if (timeout <= 0)
61 return -EIO;
62 return 0;
63}
64
65int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
66{
67 struct cavium_mdiobus *p = bus->priv;
68 union cvmx_smix_cmd smi_cmd;
69 union cvmx_smix_rd_dat smi_rd;
70 unsigned int op = 1; /* MDIO_CLAUSE_22_READ */
71 int timeout = 1000;
72
73 if (regnum & MII_ADDR_C45) {
74 int r = cavium_mdiobus_c45_addr(p, phy_id, regnum);
75
76 if (r < 0)
77 return r;
78
79 regnum = (regnum >> 16) & 0x1f;
80 op = 3; /* MDIO_CLAUSE_45_READ */
81 } else {
82 cavium_mdiobus_set_mode(p, C22);
83 }
84
85 smi_cmd.u64 = 0;
86 smi_cmd.s.phy_op = op;
87 smi_cmd.s.phy_adr = phy_id;
88 smi_cmd.s.reg_adr = regnum;
89 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
90
91 do {
92 /* Wait 1000 clocks so we don't saturate the RSL bus
93 * doing reads.
94 */
95 __delay(1000);
96 smi_rd.u64 = oct_mdio_readq(p->register_base + SMI_RD_DAT);
97 } while (smi_rd.s.pending && --timeout);
98
99 if (smi_rd.s.val)
100 return smi_rd.s.dat;
101 else
102 return -EIO;
103}
104EXPORT_SYMBOL(cavium_mdiobus_read);
105
106int cavium_mdiobus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val)
107{
108 struct cavium_mdiobus *p = bus->priv;
109 union cvmx_smix_cmd smi_cmd;
110 union cvmx_smix_wr_dat smi_wr;
111 unsigned int op = 0; /* MDIO_CLAUSE_22_WRITE */
112 int timeout = 1000;
113
114 if (regnum & MII_ADDR_C45) {
115 int r = cavium_mdiobus_c45_addr(p, phy_id, regnum);
116
117 if (r < 0)
118 return r;
119
120 regnum = (regnum >> 16) & 0x1f;
121 op = 1; /* MDIO_CLAUSE_45_WRITE */
122 } else {
123 cavium_mdiobus_set_mode(p, C22);
124 }
125
126 smi_wr.u64 = 0;
127 smi_wr.s.dat = val;
128 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
129
130 smi_cmd.u64 = 0;
131 smi_cmd.s.phy_op = op;
132 smi_cmd.s.phy_adr = phy_id;
133 smi_cmd.s.reg_adr = regnum;
134 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
135
136 do {
137 /* Wait 1000 clocks so we don't saturate the RSL bus
138 * doing reads.
139 */
140 __delay(1000);
141 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
142 } while (smi_wr.s.pending && --timeout);
143
144 if (timeout <= 0)
145 return -EIO;
146
147 return 0;
148}
149EXPORT_SYMBOL(cavium_mdiobus_write);
diff --git a/drivers/net/phy/mdio-cavium.h b/drivers/net/phy/mdio-cavium.h
new file mode 100644
index 000000000000..4bccd45d24e2
--- /dev/null
+++ b/drivers/net/phy/mdio-cavium.h
@@ -0,0 +1,119 @@
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) 2009-2016 Cavium, Inc.
7 */
8
9enum cavium_mdiobus_mode {
10 UNINIT = 0,
11 C22,
12 C45
13};
14
15#define SMI_CMD 0x0
16#define SMI_WR_DAT 0x8
17#define SMI_RD_DAT 0x10
18#define SMI_CLK 0x18
19#define SMI_EN 0x20
20
21#ifdef __BIG_ENDIAN_BITFIELD
22#define OCT_MDIO_BITFIELD_FIELD(field, more) \
23 field; \
24 more
25
26#else
27#define OCT_MDIO_BITFIELD_FIELD(field, more) \
28 more \
29 field;
30
31#endif
32
33union cvmx_smix_clk {
34 u64 u64;
35 struct cvmx_smix_clk_s {
36 OCT_MDIO_BITFIELD_FIELD(u64 reserved_25_63:39,
37 OCT_MDIO_BITFIELD_FIELD(u64 mode:1,
38 OCT_MDIO_BITFIELD_FIELD(u64 reserved_21_23:3,
39 OCT_MDIO_BITFIELD_FIELD(u64 sample_hi:5,
40 OCT_MDIO_BITFIELD_FIELD(u64 sample_mode:1,
41 OCT_MDIO_BITFIELD_FIELD(u64 reserved_14_14:1,
42 OCT_MDIO_BITFIELD_FIELD(u64 clk_idle:1,
43 OCT_MDIO_BITFIELD_FIELD(u64 preamble:1,
44 OCT_MDIO_BITFIELD_FIELD(u64 sample:4,
45 OCT_MDIO_BITFIELD_FIELD(u64 phase:8,
46 ;))))))))))
47 } s;
48};
49
50union cvmx_smix_cmd {
51 u64 u64;
52 struct cvmx_smix_cmd_s {
53 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
54 OCT_MDIO_BITFIELD_FIELD(u64 phy_op:2,
55 OCT_MDIO_BITFIELD_FIELD(u64 reserved_13_15:3,
56 OCT_MDIO_BITFIELD_FIELD(u64 phy_adr:5,
57 OCT_MDIO_BITFIELD_FIELD(u64 reserved_5_7:3,
58 OCT_MDIO_BITFIELD_FIELD(u64 reg_adr:5,
59 ;))))))
60 } s;
61};
62
63union cvmx_smix_en {
64 u64 u64;
65 struct cvmx_smix_en_s {
66 OCT_MDIO_BITFIELD_FIELD(u64 reserved_1_63:63,
67 OCT_MDIO_BITFIELD_FIELD(u64 en:1,
68 ;))
69 } s;
70};
71
72union cvmx_smix_rd_dat {
73 u64 u64;
74 struct cvmx_smix_rd_dat_s {
75 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
76 OCT_MDIO_BITFIELD_FIELD(u64 pending:1,
77 OCT_MDIO_BITFIELD_FIELD(u64 val:1,
78 OCT_MDIO_BITFIELD_FIELD(u64 dat:16,
79 ;))))
80 } s;
81};
82
83union cvmx_smix_wr_dat {
84 u64 u64;
85 struct cvmx_smix_wr_dat_s {
86 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
87 OCT_MDIO_BITFIELD_FIELD(u64 pending:1,
88 OCT_MDIO_BITFIELD_FIELD(u64 val:1,
89 OCT_MDIO_BITFIELD_FIELD(u64 dat:16,
90 ;))))
91 } s;
92};
93
94struct cavium_mdiobus {
95 struct mii_bus *mii_bus;
96 u64 register_base;
97 enum cavium_mdiobus_mode mode;
98};
99
100#ifdef CONFIG_CAVIUM_OCTEON_SOC
101
102#include <asm/octeon/octeon.h>
103
104static inline void oct_mdio_writeq(u64 val, u64 addr)
105{
106 cvmx_write_csr(addr, val);
107}
108
109static inline u64 oct_mdio_readq(u64 addr)
110{
111 return cvmx_read_csr(addr);
112}
113#else
114#define oct_mdio_writeq(val, addr) writeq(val, (void *)addr)
115#define oct_mdio_readq(addr) readq((void *)addr)
116#endif
117
118int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum);
119int cavium_mdiobus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val);
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index 47d4f2f263d1..ab6914f8bd50 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -3,272 +3,26 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2009-2012 Cavium, Inc. 6 * Copyright (C) 2009-2015 Cavium, Inc.
7 */ 7 */
8 8
9#include <linux/platform_device.h> 9#include <linux/platform_device.h>
10#include <linux/of_address.h> 10#include <linux/of_address.h>
11#include <linux/of_mdio.h> 11#include <linux/of_mdio.h>
12#include <linux/delay.h>
13#include <linux/module.h> 12#include <linux/module.h>
14#include <linux/gfp.h> 13#include <linux/gfp.h>
15#include <linux/phy.h> 14#include <linux/phy.h>
16#include <linux/io.h> 15#include <linux/io.h>
17 16
18#ifdef CONFIG_CAVIUM_OCTEON_SOC 17#include "mdio-cavium.h"
19#include <asm/octeon/octeon.h>
20#endif
21
22#define DRV_VERSION "1.1"
23#define DRV_DESCRIPTION "Cavium Networks Octeon/ThunderX SMI/MDIO driver"
24
25#define SMI_CMD 0x0
26#define SMI_WR_DAT 0x8
27#define SMI_RD_DAT 0x10
28#define SMI_CLK 0x18
29#define SMI_EN 0x20
30
31#ifdef __BIG_ENDIAN_BITFIELD
32#define OCT_MDIO_BITFIELD_FIELD(field, more) \
33 field; \
34 more
35
36#else
37#define OCT_MDIO_BITFIELD_FIELD(field, more) \
38 more \
39 field;
40
41#endif
42
43union cvmx_smix_clk {
44 u64 u64;
45 struct cvmx_smix_clk_s {
46 OCT_MDIO_BITFIELD_FIELD(u64 reserved_25_63:39,
47 OCT_MDIO_BITFIELD_FIELD(u64 mode:1,
48 OCT_MDIO_BITFIELD_FIELD(u64 reserved_21_23:3,
49 OCT_MDIO_BITFIELD_FIELD(u64 sample_hi:5,
50 OCT_MDIO_BITFIELD_FIELD(u64 sample_mode:1,
51 OCT_MDIO_BITFIELD_FIELD(u64 reserved_14_14:1,
52 OCT_MDIO_BITFIELD_FIELD(u64 clk_idle:1,
53 OCT_MDIO_BITFIELD_FIELD(u64 preamble:1,
54 OCT_MDIO_BITFIELD_FIELD(u64 sample:4,
55 OCT_MDIO_BITFIELD_FIELD(u64 phase:8,
56 ;))))))))))
57 } s;
58};
59
60union cvmx_smix_cmd {
61 u64 u64;
62 struct cvmx_smix_cmd_s {
63 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
64 OCT_MDIO_BITFIELD_FIELD(u64 phy_op:2,
65 OCT_MDIO_BITFIELD_FIELD(u64 reserved_13_15:3,
66 OCT_MDIO_BITFIELD_FIELD(u64 phy_adr:5,
67 OCT_MDIO_BITFIELD_FIELD(u64 reserved_5_7:3,
68 OCT_MDIO_BITFIELD_FIELD(u64 reg_adr:5,
69 ;))))))
70 } s;
71};
72
73union cvmx_smix_en {
74 u64 u64;
75 struct cvmx_smix_en_s {
76 OCT_MDIO_BITFIELD_FIELD(u64 reserved_1_63:63,
77 OCT_MDIO_BITFIELD_FIELD(u64 en:1,
78 ;))
79 } s;
80};
81
82union cvmx_smix_rd_dat {
83 u64 u64;
84 struct cvmx_smix_rd_dat_s {
85 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
86 OCT_MDIO_BITFIELD_FIELD(u64 pending:1,
87 OCT_MDIO_BITFIELD_FIELD(u64 val:1,
88 OCT_MDIO_BITFIELD_FIELD(u64 dat:16,
89 ;))))
90 } s;
91};
92
93union cvmx_smix_wr_dat {
94 u64 u64;
95 struct cvmx_smix_wr_dat_s {
96 OCT_MDIO_BITFIELD_FIELD(u64 reserved_18_63:46,
97 OCT_MDIO_BITFIELD_FIELD(u64 pending:1,
98 OCT_MDIO_BITFIELD_FIELD(u64 val:1,
99 OCT_MDIO_BITFIELD_FIELD(u64 dat:16,
100 ;))))
101 } s;
102};
103
104enum octeon_mdiobus_mode {
105 UNINIT = 0,
106 C22,
107 C45
108};
109
110struct octeon_mdiobus {
111 struct mii_bus *mii_bus;
112 u64 register_base;
113 resource_size_t mdio_phys;
114 resource_size_t regsize;
115 enum octeon_mdiobus_mode mode;
116};
117
118#ifdef CONFIG_CAVIUM_OCTEON_SOC
119static void oct_mdio_writeq(u64 val, u64 addr)
120{
121 cvmx_write_csr(addr, val);
122}
123
124static u64 oct_mdio_readq(u64 addr)
125{
126 return cvmx_read_csr(addr);
127}
128#else
129#define oct_mdio_writeq(val, addr) writeq_relaxed(val, (void *)addr)
130#define oct_mdio_readq(addr) readq_relaxed((void *)addr)
131#endif
132
133static void octeon_mdiobus_set_mode(struct octeon_mdiobus *p,
134 enum octeon_mdiobus_mode m)
135{
136 union cvmx_smix_clk smi_clk;
137
138 if (m == p->mode)
139 return;
140
141 smi_clk.u64 = oct_mdio_readq(p->register_base + SMI_CLK);
142 smi_clk.s.mode = (m == C45) ? 1 : 0;
143 smi_clk.s.preamble = 1;
144 oct_mdio_writeq(smi_clk.u64, p->register_base + SMI_CLK);
145 p->mode = m;
146}
147
148static int octeon_mdiobus_c45_addr(struct octeon_mdiobus *p,
149 int phy_id, int regnum)
150{
151 union cvmx_smix_cmd smi_cmd;
152 union cvmx_smix_wr_dat smi_wr;
153 int timeout = 1000;
154
155 octeon_mdiobus_set_mode(p, C45);
156
157 smi_wr.u64 = 0;
158 smi_wr.s.dat = regnum & 0xffff;
159 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
160
161 regnum = (regnum >> 16) & 0x1f;
162
163 smi_cmd.u64 = 0;
164 smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_45_ADDRESS */
165 smi_cmd.s.phy_adr = phy_id;
166 smi_cmd.s.reg_adr = regnum;
167 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
168
169 do {
170 /* Wait 1000 clocks so we don't saturate the RSL bus
171 * doing reads.
172 */
173 __delay(1000);
174 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
175 } while (smi_wr.s.pending && --timeout);
176
177 if (timeout <= 0)
178 return -EIO;
179 return 0;
180}
181
182static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
183{
184 struct octeon_mdiobus *p = bus->priv;
185 union cvmx_smix_cmd smi_cmd;
186 union cvmx_smix_rd_dat smi_rd;
187 unsigned int op = 1; /* MDIO_CLAUSE_22_READ */
188 int timeout = 1000;
189
190 if (regnum & MII_ADDR_C45) {
191 int r = octeon_mdiobus_c45_addr(p, phy_id, regnum);
192 if (r < 0)
193 return r;
194
195 regnum = (regnum >> 16) & 0x1f;
196 op = 3; /* MDIO_CLAUSE_45_READ */
197 } else {
198 octeon_mdiobus_set_mode(p, C22);
199 }
200
201
202 smi_cmd.u64 = 0;
203 smi_cmd.s.phy_op = op;
204 smi_cmd.s.phy_adr = phy_id;
205 smi_cmd.s.reg_adr = regnum;
206 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
207
208 do {
209 /* Wait 1000 clocks so we don't saturate the RSL bus
210 * doing reads.
211 */
212 __delay(1000);
213 smi_rd.u64 = oct_mdio_readq(p->register_base + SMI_RD_DAT);
214 } while (smi_rd.s.pending && --timeout);
215
216 if (smi_rd.s.val)
217 return smi_rd.s.dat;
218 else
219 return -EIO;
220}
221
222static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
223 int regnum, u16 val)
224{
225 struct octeon_mdiobus *p = bus->priv;
226 union cvmx_smix_cmd smi_cmd;
227 union cvmx_smix_wr_dat smi_wr;
228 unsigned int op = 0; /* MDIO_CLAUSE_22_WRITE */
229 int timeout = 1000;
230
231
232 if (regnum & MII_ADDR_C45) {
233 int r = octeon_mdiobus_c45_addr(p, phy_id, regnum);
234 if (r < 0)
235 return r;
236
237 regnum = (regnum >> 16) & 0x1f;
238 op = 1; /* MDIO_CLAUSE_45_WRITE */
239 } else {
240 octeon_mdiobus_set_mode(p, C22);
241 }
242
243 smi_wr.u64 = 0;
244 smi_wr.s.dat = val;
245 oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
246
247 smi_cmd.u64 = 0;
248 smi_cmd.s.phy_op = op;
249 smi_cmd.s.phy_adr = phy_id;
250 smi_cmd.s.reg_adr = regnum;
251 oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
252
253 do {
254 /* Wait 1000 clocks so we don't saturate the RSL bus
255 * doing reads.
256 */
257 __delay(1000);
258 smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
259 } while (smi_wr.s.pending && --timeout);
260
261 if (timeout <= 0)
262 return -EIO;
263
264 return 0;
265}
266 18
267static int octeon_mdiobus_probe(struct platform_device *pdev) 19static int octeon_mdiobus_probe(struct platform_device *pdev)
268{ 20{
269 struct octeon_mdiobus *bus; 21 struct cavium_mdiobus *bus;
270 struct mii_bus *mii_bus; 22 struct mii_bus *mii_bus;
271 struct resource *res_mem; 23 struct resource *res_mem;
24 resource_size_t mdio_phys;
25 resource_size_t regsize;
272 union cvmx_smix_en smi_en; 26 union cvmx_smix_en smi_en;
273 int err = -ENOENT; 27 int err = -ENOENT;
274 28
@@ -284,17 +38,17 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
284 38
285 bus = mii_bus->priv; 39 bus = mii_bus->priv;
286 bus->mii_bus = mii_bus; 40 bus->mii_bus = mii_bus;
287 bus->mdio_phys = res_mem->start; 41 mdio_phys = res_mem->start;
288 bus->regsize = resource_size(res_mem); 42 regsize = resource_size(res_mem);
289 43
290 if (!devm_request_mem_region(&pdev->dev, bus->mdio_phys, bus->regsize, 44 if (!devm_request_mem_region(&pdev->dev, mdio_phys, regsize,
291 res_mem->name)) { 45 res_mem->name)) {
292 dev_err(&pdev->dev, "request_mem_region failed\n"); 46 dev_err(&pdev->dev, "request_mem_region failed\n");
293 return -ENXIO; 47 return -ENXIO;
294 } 48 }
295 49
296 bus->register_base = 50 bus->register_base =
297 (u64)devm_ioremap(&pdev->dev, bus->mdio_phys, bus->regsize); 51 (u64)devm_ioremap(&pdev->dev, mdio_phys, regsize);
298 if (!bus->register_base) { 52 if (!bus->register_base) {
299 dev_err(&pdev->dev, "dev_ioremap failed\n"); 53 dev_err(&pdev->dev, "dev_ioremap failed\n");
300 return -ENOMEM; 54 return -ENOMEM;
@@ -304,13 +58,12 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
304 smi_en.s.en = 1; 58 smi_en.s.en = 1;
305 oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); 59 oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN);
306 60
307 bus->mii_bus->priv = bus; 61 bus->mii_bus->name = KBUILD_MODNAME;
308 bus->mii_bus->name = "mdio-octeon";
309 snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", bus->register_base); 62 snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", bus->register_base);
310 bus->mii_bus->parent = &pdev->dev; 63 bus->mii_bus->parent = &pdev->dev;
311 64
312 bus->mii_bus->read = octeon_mdiobus_read; 65 bus->mii_bus->read = cavium_mdiobus_read;
313 bus->mii_bus->write = octeon_mdiobus_write; 66 bus->mii_bus->write = cavium_mdiobus_write;
314 67
315 platform_set_drvdata(pdev, bus); 68 platform_set_drvdata(pdev, bus);
316 69
@@ -318,7 +71,7 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
318 if (err) 71 if (err)
319 goto fail_register; 72 goto fail_register;
320 73
321 dev_info(&pdev->dev, "Version " DRV_VERSION "\n"); 74 dev_info(&pdev->dev, "Probed\n");
322 75
323 return 0; 76 return 0;
324fail_register: 77fail_register:
@@ -330,7 +83,7 @@ fail_register:
330 83
331static int octeon_mdiobus_remove(struct platform_device *pdev) 84static int octeon_mdiobus_remove(struct platform_device *pdev)
332{ 85{
333 struct octeon_mdiobus *bus; 86 struct cavium_mdiobus *bus;
334 union cvmx_smix_en smi_en; 87 union cvmx_smix_en smi_en;
335 88
336 bus = platform_get_drvdata(pdev); 89 bus = platform_get_drvdata(pdev);
@@ -352,7 +105,7 @@ MODULE_DEVICE_TABLE(of, octeon_mdiobus_match);
352 105
353static struct platform_driver octeon_mdiobus_driver = { 106static struct platform_driver octeon_mdiobus_driver = {
354 .driver = { 107 .driver = {
355 .name = "mdio-octeon", 108 .name = KBUILD_MODNAME,
356 .of_match_table = octeon_mdiobus_match, 109 .of_match_table = octeon_mdiobus_match,
357 }, 110 },
358 .probe = octeon_mdiobus_probe, 111 .probe = octeon_mdiobus_probe,
@@ -367,7 +120,6 @@ EXPORT_SYMBOL(octeon_mdiobus_force_mod_depencency);
367 120
368module_platform_driver(octeon_mdiobus_driver); 121module_platform_driver(octeon_mdiobus_driver);
369 122
370MODULE_DESCRIPTION(DRV_DESCRIPTION); 123MODULE_DESCRIPTION("Cavium OCTEON MDIO bus driver");
371MODULE_VERSION(DRV_VERSION);
372MODULE_AUTHOR("David Daney"); 124MODULE_AUTHOR("David Daney");
373MODULE_LICENSE("GPL"); 125MODULE_LICENSE("GPL");