Skip to content

Commit e57e5e7

Browse files
viviendavem330
authored andcommitted
net: dsa: mv88e6xxx: abstract PHY ops
Old chips use a direct access to the PHY devices registers. Next chips have a PHY Polling Unit (PPU) which needs to be disabled before accessing PHY registers. Newer chips have an indirect access to the PHY devices so that disabling the PPU is not necessary. Introduce a new phy_ops structure in the chip to describe the required PHY access routines. Signed-off-by: Vivien Didelot <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 57c67cf commit e57e5e7

File tree

2 files changed

+81
-51
lines changed

2 files changed

+81
-51
lines changed

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 80 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,28 @@ static int mv88e6xxx_write(struct mv88e6xxx_chip *chip,
216216
return 0;
217217
}
218218

219+
static int mv88e6xxx_phy_read(struct mv88e6xxx_chip *chip, int phy,
220+
int reg, u16 *val)
221+
{
222+
int addr = phy; /* PHY devices addresses start at 0x0 */
223+
224+
if (!chip->phy_ops)
225+
return -EOPNOTSUPP;
226+
227+
return chip->phy_ops->read(chip, addr, reg, val);
228+
}
229+
230+
static int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy,
231+
int reg, u16 val)
232+
{
233+
int addr = phy; /* PHY devices addresses start at 0x0 */
234+
235+
if (!chip->phy_ops)
236+
return -EOPNOTSUPP;
237+
238+
return chip->phy_ops->write(chip, addr, reg, val);
239+
}
240+
219241
static int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg,
220242
u16 mask)
221243
{
@@ -422,34 +444,39 @@ static void mv88e6xxx_ppu_state_init(struct mv88e6xxx_chip *chip)
422444
chip->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
423445
}
424446

425-
static int mv88e6xxx_mdio_read_ppu(struct mv88e6xxx_chip *chip, int addr,
426-
int regnum)
447+
static int mv88e6xxx_phy_ppu_read(struct mv88e6xxx_chip *chip, int addr,
448+
int reg, u16 *val)
427449
{
428-
int ret;
450+
int err;
429451

430-
ret = mv88e6xxx_ppu_access_get(chip);
431-
if (ret >= 0) {
432-
ret = _mv88e6xxx_reg_read(chip, addr, regnum);
452+
err = mv88e6xxx_ppu_access_get(chip);
453+
if (!err) {
454+
err = mv88e6xxx_read(chip, addr, reg, val);
433455
mv88e6xxx_ppu_access_put(chip);
434456
}
435457

436-
return ret;
458+
return err;
437459
}
438460

439-
static int mv88e6xxx_mdio_write_ppu(struct mv88e6xxx_chip *chip, int addr,
440-
int regnum, u16 val)
461+
static int mv88e6xxx_phy_ppu_write(struct mv88e6xxx_chip *chip, int addr,
462+
int reg, u16 val)
441463
{
442-
int ret;
464+
int err;
443465

444-
ret = mv88e6xxx_ppu_access_get(chip);
445-
if (ret >= 0) {
446-
ret = _mv88e6xxx_reg_write(chip, addr, regnum, val);
466+
err = mv88e6xxx_ppu_access_get(chip);
467+
if (!err) {
468+
err = mv88e6xxx_write(chip, addr, reg, val);
447469
mv88e6xxx_ppu_access_put(chip);
448470
}
449471

450-
return ret;
472+
return err;
451473
}
452474

475+
static const struct mv88e6xxx_ops mv88e6xxx_phy_ppu_ops = {
476+
.read = mv88e6xxx_phy_ppu_read,
477+
.write = mv88e6xxx_phy_ppu_write,
478+
};
479+
453480
static bool mv88e6xxx_6065_family(struct mv88e6xxx_chip *chip)
454481
{
455482
return chip->info->family == MV88E6XXX_FAMILY_6065;
@@ -3090,6 +3117,11 @@ static int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, int addr,
30903117
return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
30913118
}
30923119

3120+
static const struct mv88e6xxx_ops mv88e6xxx_g2_smi_phy_ops = {
3121+
.read = mv88e6xxx_g2_smi_phy_read,
3122+
.write = mv88e6xxx_g2_smi_phy_write,
3123+
};
3124+
30933125
static int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
30943126
{
30953127
u16 reg;
@@ -3249,56 +3281,35 @@ static int mv88e6xxx_mdio_page_write(struct dsa_switch *ds, int port, int page,
32493281
return ret;
32503282
}
32513283

3252-
static int mv88e6xxx_port_to_mdio_addr(struct mv88e6xxx_chip *chip, int port)
3253-
{
3254-
if (port >= 0 && port < chip->info->num_ports)
3255-
return port;
3256-
return -EINVAL;
3257-
}
3258-
3259-
static int mv88e6xxx_mdio_read(struct mii_bus *bus, int port, int regnum)
3284+
static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
32603285
{
32613286
struct mv88e6xxx_chip *chip = bus->priv;
3262-
int addr = mv88e6xxx_port_to_mdio_addr(chip, port);
3263-
int ret;
3287+
u16 val;
3288+
int err;
32643289

3265-
if (addr < 0)
3290+
if (phy >= chip->info->num_ports)
32663291
return 0xffff;
32673292

32683293
mutex_lock(&chip->reg_lock);
3269-
3270-
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
3271-
ret = mv88e6xxx_mdio_read_ppu(chip, addr, regnum);
3272-
else if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_SMI_PHY))
3273-
ret = mv88e6xxx_mdio_read_indirect(chip, addr, regnum);
3274-
else
3275-
ret = mv88e6xxx_mdio_read_direct(chip, addr, regnum);
3276-
3294+
err = mv88e6xxx_phy_read(chip, phy, reg, &val);
32773295
mutex_unlock(&chip->reg_lock);
3278-
return ret;
3296+
3297+
return err ? err : val;
32793298
}
32803299

3281-
static int mv88e6xxx_mdio_write(struct mii_bus *bus, int port, int regnum,
3282-
u16 val)
3300+
static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
32833301
{
32843302
struct mv88e6xxx_chip *chip = bus->priv;
3285-
int addr = mv88e6xxx_port_to_mdio_addr(chip, port);
3286-
int ret;
3303+
int err;
32873304

3288-
if (addr < 0)
3305+
if (phy >= chip->info->num_ports)
32893306
return 0xffff;
32903307

32913308
mutex_lock(&chip->reg_lock);
3292-
3293-
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
3294-
ret = mv88e6xxx_mdio_write_ppu(chip, addr, regnum, val);
3295-
else if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_SMI_PHY))
3296-
ret = mv88e6xxx_mdio_write_indirect(chip, addr, regnum, val);
3297-
else
3298-
ret = mv88e6xxx_mdio_write_direct(chip, addr, regnum, val);
3299-
3309+
err = mv88e6xxx_phy_write(chip, phy, reg, val);
33003310
mutex_unlock(&chip->reg_lock);
3301-
return ret;
3311+
3312+
return err;
33023313
}
33033314

33043315
static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
@@ -3308,9 +3319,6 @@ static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
33083319
struct mii_bus *bus;
33093320
int err;
33103321

3311-
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
3312-
mv88e6xxx_ppu_state_init(chip);
3313-
33143322
if (np)
33153323
chip->mdio_np = of_get_child_by_name(np, "mdio");
33163324

@@ -3907,6 +3915,23 @@ static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
39073915
return chip;
39083916
}
39093917

3918+
static const struct mv88e6xxx_ops mv88e6xxx_phy_ops = {
3919+
.read = mv88e6xxx_read,
3920+
.write = mv88e6xxx_write,
3921+
};
3922+
3923+
static void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip)
3924+
{
3925+
if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_SMI_PHY)) {
3926+
chip->phy_ops = &mv88e6xxx_g2_smi_phy_ops;
3927+
} else if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU)) {
3928+
chip->phy_ops = &mv88e6xxx_phy_ppu_ops;
3929+
mv88e6xxx_ppu_state_init(chip);
3930+
} else {
3931+
chip->phy_ops = &mv88e6xxx_phy_ops;
3932+
}
3933+
}
3934+
39103935
static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
39113936
struct mii_bus *bus, int sw_addr)
39123937
{
@@ -3954,6 +3979,8 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
39543979
if (err)
39553980
goto free;
39563981

3982+
mv88e6xxx_phy_init(chip);
3983+
39573984
err = mv88e6xxx_mdio_register(chip, NULL);
39583985
if (err)
39593986
goto free;
@@ -4055,6 +4082,8 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
40554082
if (err)
40564083
return err;
40574084

4085+
mv88e6xxx_phy_init(chip);
4086+
40584087
chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
40594088
if (IS_ERR(chip->reset))
40604089
return PTR_ERR(chip->reset);

drivers/net/dsa/mv88e6xxx/mv88e6xxx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ struct mv88e6xxx_chip {
634634
/* Handles automatic disabling and re-enabling of the PHY
635635
* polling unit.
636636
*/
637+
const struct mv88e6xxx_ops *phy_ops;
637638
struct mutex ppu_mutex;
638639
int ppu_disabled;
639640
struct work_struct ppu_work;

0 commit comments

Comments
 (0)