Skip to content

Commit 002dd3d

Browse files
lunnkuba-moo
authored andcommitted
net: mdio: mdio-bitbang: Separate C22 and C45 transactions
The bitbbanging bus driver can perform both C22 and C45 transfers. Create separate functions for each and register the C45 versions using the new driver API calls. The SH Ethernet driver places wrappers around these functions. In order to not break boards which might be using C45, add similar wrappers for C45 operations. Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Michael Walle <michael@walle.cc> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent ce30fa5 commit 002dd3d

File tree

4 files changed

+130
-40
lines changed

4 files changed

+130
-40
lines changed

drivers/net/ethernet/renesas/sh_eth.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3044,23 +3044,46 @@ static int sh_mdio_release(struct sh_eth_private *mdp)
30443044
return 0;
30453045
}
30463046

3047-
static int sh_mdiobb_read(struct mii_bus *bus, int phy, int reg)
3047+
static int sh_mdiobb_read_c22(struct mii_bus *bus, int phy, int reg)
30483048
{
30493049
int res;
30503050

30513051
pm_runtime_get_sync(bus->parent);
3052-
res = mdiobb_read(bus, phy, reg);
3052+
res = mdiobb_read_c22(bus, phy, reg);
30533053
pm_runtime_put(bus->parent);
30543054

30553055
return res;
30563056
}
30573057

3058-
static int sh_mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
3058+
static int sh_mdiobb_write_c22(struct mii_bus *bus, int phy, int reg, u16 val)
30593059
{
30603060
int res;
30613061

30623062
pm_runtime_get_sync(bus->parent);
3063-
res = mdiobb_write(bus, phy, reg, val);
3063+
res = mdiobb_write_c22(bus, phy, reg, val);
3064+
pm_runtime_put(bus->parent);
3065+
3066+
return res;
3067+
}
3068+
3069+
static int sh_mdiobb_read_c45(struct mii_bus *bus, int phy, int devad, int reg)
3070+
{
3071+
int res;
3072+
3073+
pm_runtime_get_sync(bus->parent);
3074+
res = mdiobb_read_c45(bus, phy, devad, reg);
3075+
pm_runtime_put(bus->parent);
3076+
3077+
return res;
3078+
}
3079+
3080+
static int sh_mdiobb_write_c45(struct mii_bus *bus, int phy, int devad,
3081+
int reg, u16 val)
3082+
{
3083+
int res;
3084+
3085+
pm_runtime_get_sync(bus->parent);
3086+
res = mdiobb_write_c45(bus, phy, devad, reg, val);
30643087
pm_runtime_put(bus->parent);
30653088

30663089
return res;
@@ -3091,8 +3114,10 @@ static int sh_mdio_init(struct sh_eth_private *mdp,
30913114
return -ENOMEM;
30923115

30933116
/* Wrap accessors with Runtime PM-aware ops */
3094-
mdp->mii_bus->read = sh_mdiobb_read;
3095-
mdp->mii_bus->write = sh_mdiobb_write;
3117+
mdp->mii_bus->read = sh_mdiobb_read_c22;
3118+
mdp->mii_bus->write = sh_mdiobb_write_c22;
3119+
mdp->mii_bus->read_c45 = sh_mdiobb_read_c45;
3120+
mdp->mii_bus->write_c45 = sh_mdiobb_write_c45;
30963121

30973122
/* Hook up MII support for ethtool */
30983123
mdp->mii_bus->name = "sh_mii";

drivers/net/ethernet/ti/davinci_mdio.c

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,32 +225,66 @@ static int davinci_get_mdio_data(struct mdiobb_ctrl *ctrl)
225225
return test_bit(MDIO_PIN, &reg);
226226
}
227227

228-
static int davinci_mdiobb_read(struct mii_bus *bus, int phy, int reg)
228+
static int davinci_mdiobb_read_c22(struct mii_bus *bus, int phy, int reg)
229229
{
230230
int ret;
231231

232232
ret = pm_runtime_resume_and_get(bus->parent);
233233
if (ret < 0)
234234
return ret;
235235

236-
ret = mdiobb_read(bus, phy, reg);
236+
ret = mdiobb_read_c22(bus, phy, reg);
237237

238238
pm_runtime_mark_last_busy(bus->parent);
239239
pm_runtime_put_autosuspend(bus->parent);
240240

241241
return ret;
242242
}
243243

244-
static int davinci_mdiobb_write(struct mii_bus *bus, int phy, int reg,
245-
u16 val)
244+
static int davinci_mdiobb_write_c22(struct mii_bus *bus, int phy, int reg,
245+
u16 val)
246246
{
247247
int ret;
248248

249249
ret = pm_runtime_resume_and_get(bus->parent);
250250
if (ret < 0)
251251
return ret;
252252

253-
ret = mdiobb_write(bus, phy, reg, val);
253+
ret = mdiobb_write_c22(bus, phy, reg, val);
254+
255+
pm_runtime_mark_last_busy(bus->parent);
256+
pm_runtime_put_autosuspend(bus->parent);
257+
258+
return ret;
259+
}
260+
261+
static int davinci_mdiobb_read_c45(struct mii_bus *bus, int phy, int devad,
262+
int reg)
263+
{
264+
int ret;
265+
266+
ret = pm_runtime_resume_and_get(bus->parent);
267+
if (ret < 0)
268+
return ret;
269+
270+
ret = mdiobb_read_c45(bus, phy, devad, reg);
271+
272+
pm_runtime_mark_last_busy(bus->parent);
273+
pm_runtime_put_autosuspend(bus->parent);
274+
275+
return ret;
276+
}
277+
278+
static int davinci_mdiobb_write_c45(struct mii_bus *bus, int phy, int devad,
279+
int reg, u16 val)
280+
{
281+
int ret;
282+
283+
ret = pm_runtime_resume_and_get(bus->parent);
284+
if (ret < 0)
285+
return ret;
286+
287+
ret = mdiobb_write_c45(bus, phy, devad, reg, val);
254288

255289
pm_runtime_mark_last_busy(bus->parent);
256290
pm_runtime_put_autosuspend(bus->parent);
@@ -573,8 +607,10 @@ static int davinci_mdio_probe(struct platform_device *pdev)
573607
data->bus->name = dev_name(dev);
574608

575609
if (data->manual_mode) {
576-
data->bus->read = davinci_mdiobb_read;
577-
data->bus->write = davinci_mdiobb_write;
610+
data->bus->read = davinci_mdiobb_read_c22;
611+
data->bus->write = davinci_mdiobb_write_c22;
612+
data->bus->read_c45 = davinci_mdiobb_read_c45;
613+
data->bus->write_c45 = davinci_mdiobb_write_c45;
578614
data->bus->reset = davinci_mdiobb_reset;
579615

580616
dev_info(dev, "Configuring MDIO in manual mode\n");

drivers/net/mdio/mdio-bitbang.c

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,12 @@ static void mdiobb_cmd(struct mdiobb_ctrl *ctrl, int op, u8 phy, u8 reg)
127127

128128
/* In clause 45 mode all commands are prefixed by MDIO_ADDR to specify the
129129
lower 16 bits of the 21 bit address. This transfer is done identically to a
130-
MDIO_WRITE except for a different code. To enable clause 45 mode or
131-
MII_ADDR_C45 into the address. Theoretically clause 45 and normal devices
132-
can exist on the same bus. Normal devices should ignore the MDIO_ADDR
130+
MDIO_WRITE except for a different code. Theoretically clause 45 and normal
131+
devices can exist on the same bus. Normal devices should ignore the MDIO_ADDR
133132
phase. */
134-
static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr)
133+
static void mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, int dev_addr,
134+
int reg)
135135
{
136-
unsigned int dev_addr = (addr >> 16) & 0x1F;
137-
unsigned int reg = addr & 0xFFFF;
138136
mdiobb_cmd(ctrl, MDIO_C45_ADDR, phy, dev_addr);
139137

140138
/* send the turnaround (10) */
@@ -145,21 +143,13 @@ static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr)
145143

146144
ctrl->ops->set_mdio_dir(ctrl, 0);
147145
mdiobb_get_bit(ctrl);
148-
149-
return dev_addr;
150146
}
151147

152-
int mdiobb_read(struct mii_bus *bus, int phy, int reg)
148+
static int mdiobb_read_common(struct mii_bus *bus, int phy)
153149
{
154150
struct mdiobb_ctrl *ctrl = bus->priv;
155151
int ret, i;
156152

157-
if (reg & MII_ADDR_C45) {
158-
reg = mdiobb_cmd_addr(ctrl, phy, reg);
159-
mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
160-
} else
161-
mdiobb_cmd(ctrl, ctrl->op_c22_read, phy, reg);
162-
163153
ctrl->ops->set_mdio_dir(ctrl, 0);
164154

165155
/* check the turnaround bit: the PHY should be driving it to zero, if this
@@ -180,17 +170,31 @@ int mdiobb_read(struct mii_bus *bus, int phy, int reg)
180170
mdiobb_get_bit(ctrl);
181171
return ret;
182172
}
183-
EXPORT_SYMBOL(mdiobb_read);
184173

185-
int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
174+
int mdiobb_read_c22(struct mii_bus *bus, int phy, int reg)
186175
{
187176
struct mdiobb_ctrl *ctrl = bus->priv;
188177

189-
if (reg & MII_ADDR_C45) {
190-
reg = mdiobb_cmd_addr(ctrl, phy, reg);
191-
mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
192-
} else
193-
mdiobb_cmd(ctrl, ctrl->op_c22_write, phy, reg);
178+
mdiobb_cmd(ctrl, ctrl->op_c22_read, phy, reg);
179+
180+
return mdiobb_read_common(bus, phy);
181+
}
182+
EXPORT_SYMBOL(mdiobb_read_c22);
183+
184+
int mdiobb_read_c45(struct mii_bus *bus, int phy, int devad, int reg)
185+
{
186+
struct mdiobb_ctrl *ctrl = bus->priv;
187+
188+
mdiobb_cmd_addr(ctrl, phy, devad, reg);
189+
mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
190+
191+
return mdiobb_read_common(bus, phy);
192+
}
193+
EXPORT_SYMBOL(mdiobb_read_c45);
194+
195+
static int mdiobb_write_common(struct mii_bus *bus, u16 val)
196+
{
197+
struct mdiobb_ctrl *ctrl = bus->priv;
194198

195199
/* send the turnaround (10) */
196200
mdiobb_send_bit(ctrl, 1);
@@ -202,7 +206,27 @@ int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
202206
mdiobb_get_bit(ctrl);
203207
return 0;
204208
}
205-
EXPORT_SYMBOL(mdiobb_write);
209+
210+
int mdiobb_write_c22(struct mii_bus *bus, int phy, int reg, u16 val)
211+
{
212+
struct mdiobb_ctrl *ctrl = bus->priv;
213+
214+
mdiobb_cmd(ctrl, ctrl->op_c22_write, phy, reg);
215+
216+
return mdiobb_write_common(bus, val);
217+
}
218+
EXPORT_SYMBOL(mdiobb_write_c22);
219+
220+
int mdiobb_write_c45(struct mii_bus *bus, int phy, int devad, int reg, u16 val)
221+
{
222+
struct mdiobb_ctrl *ctrl = bus->priv;
223+
224+
mdiobb_cmd_addr(ctrl, phy, devad, reg);
225+
mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
226+
227+
return mdiobb_write_common(bus, val);
228+
}
229+
EXPORT_SYMBOL(mdiobb_write_c45);
206230

207231
struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
208232
{
@@ -214,8 +238,11 @@ struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
214238

215239
__module_get(ctrl->ops->owner);
216240

217-
bus->read = mdiobb_read;
218-
bus->write = mdiobb_write;
241+
bus->read = mdiobb_read_c22;
242+
bus->write = mdiobb_write_c22;
243+
bus->read_c45 = mdiobb_read_c45;
244+
bus->write_c45 = mdiobb_write_c45;
245+
219246
bus->priv = ctrl;
220247
if (!ctrl->override_op_c22) {
221248
ctrl->op_c22_read = MDIO_READ;

include/linux/mdio-bitbang.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ struct mdiobb_ctrl {
3838
u8 op_c22_write;
3939
};
4040

41-
int mdiobb_read(struct mii_bus *bus, int phy, int reg);
42-
int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val);
41+
int mdiobb_read_c22(struct mii_bus *bus, int phy, int reg);
42+
int mdiobb_write_c22(struct mii_bus *bus, int phy, int reg, u16 val);
43+
int mdiobb_read_c45(struct mii_bus *bus, int devad, int phy, int reg);
44+
int mdiobb_write_c45(struct mii_bus *bus, int devad, int phy, int reg, u16 val);
4345

4446
/* The returned bus is not yet registered with the phy layer. */
4547
struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl);

0 commit comments

Comments
 (0)